| 
									
										
										
										
											1993-12-24 10:32:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-12-18 22:02:37 +00:00
										 |  |  | #include "Python.h"
 | 
					
						
							| 
									
										
										
										
											1994-08-01 11:34:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-07-07 21:32:53 +00:00
										 |  |  | #if defined(__sgi) && defined(WITH_THREAD) && !defined(_SGI_MP_SOURCE)
 | 
					
						
							|  |  |  | #define _SGI_MP_SOURCE
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-02-10 17:01:56 +00:00
										 |  |  | /* Convert a possibly signed character to a nonnegative int */ | 
					
						
							|  |  |  | /* XXX This assumes characters are 8 bits wide */ | 
					
						
							|  |  |  | #ifdef __CHAR_UNSIGNED__
 | 
					
						
							|  |  |  | #define Py_CHARMASK(c)		(c)
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #define Py_CHARMASK(c)		((c) & 0xff)
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-08-01 11:34:53 +00:00
										 |  |  | /* strtol and strtoul, renamed to avoid conflicts */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-05-23 18:45:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <ctype.h>
 | 
					
						
							| 
									
										
										
										
											2006-06-10 12:23:46 +00:00
										 |  |  | #ifdef HAVE_ERRNO_H
 | 
					
						
							| 
									
										
										
										
											2006-05-23 18:45:30 +00:00
										 |  |  | #include <errno.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Static overflow check values for bases 2 through 36.
 | 
					
						
							|  |  |  |  * smallmax[base] is the largest unsigned long i such that | 
					
						
							|  |  |  |  * i * base doesn't overflow unsigned long. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static unsigned long smallmax[] = { | 
					
						
							|  |  |  | 	0, /* bases 0 and 1 are invalid */ | 
					
						
							|  |  |  | 	0, | 
					
						
							|  |  |  | 	ULONG_MAX / 2, | 
					
						
							|  |  |  | 	ULONG_MAX / 3, | 
					
						
							|  |  |  | 	ULONG_MAX / 4, | 
					
						
							|  |  |  | 	ULONG_MAX / 5, | 
					
						
							|  |  |  | 	ULONG_MAX / 6, | 
					
						
							|  |  |  | 	ULONG_MAX / 7, | 
					
						
							|  |  |  | 	ULONG_MAX / 8, | 
					
						
							|  |  |  | 	ULONG_MAX / 9, | 
					
						
							|  |  |  | 	ULONG_MAX / 10, | 
					
						
							|  |  |  | 	ULONG_MAX / 11, | 
					
						
							|  |  |  | 	ULONG_MAX / 12, | 
					
						
							|  |  |  | 	ULONG_MAX / 13, | 
					
						
							|  |  |  | 	ULONG_MAX / 14, | 
					
						
							|  |  |  | 	ULONG_MAX / 15, | 
					
						
							|  |  |  | 	ULONG_MAX / 16, | 
					
						
							|  |  |  | 	ULONG_MAX / 17, | 
					
						
							|  |  |  | 	ULONG_MAX / 18, | 
					
						
							|  |  |  | 	ULONG_MAX / 19, | 
					
						
							|  |  |  | 	ULONG_MAX / 20, | 
					
						
							|  |  |  | 	ULONG_MAX / 21, | 
					
						
							|  |  |  | 	ULONG_MAX / 22, | 
					
						
							|  |  |  | 	ULONG_MAX / 23, | 
					
						
							|  |  |  | 	ULONG_MAX / 24, | 
					
						
							|  |  |  | 	ULONG_MAX / 25, | 
					
						
							|  |  |  | 	ULONG_MAX / 26, | 
					
						
							|  |  |  | 	ULONG_MAX / 27, | 
					
						
							|  |  |  | 	ULONG_MAX / 28, | 
					
						
							|  |  |  | 	ULONG_MAX / 29, | 
					
						
							|  |  |  | 	ULONG_MAX / 30, | 
					
						
							|  |  |  | 	ULONG_MAX / 31, | 
					
						
							|  |  |  | 	ULONG_MAX / 32, | 
					
						
							|  |  |  | 	ULONG_MAX / 33, | 
					
						
							|  |  |  | 	ULONG_MAX / 34, | 
					
						
							|  |  |  | 	ULONG_MAX / 35, | 
					
						
							|  |  |  | 	ULONG_MAX / 36, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* maximum digits that can't ever overflow for bases 2 through 36,
 | 
					
						
							|  |  |  |  * calculated by [int(math.floor(math.log(2**32, i))) for i in range(2, 37)]. | 
					
						
							|  |  |  |  * Note that this is pessimistic if sizeof(long) > 4. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2006-07-09 22:14:42 +00:00
										 |  |  | #if SIZEOF_LONG == 4
 | 
					
						
							| 
									
										
										
										
											2006-05-23 18:45:30 +00:00
										 |  |  | static int digitlimit[] = { | 
					
						
							|  |  |  | 	0,  0, 32, 20, 16, 13, 12, 11, 10, 10,  /*  0 -  9 */ | 
					
						
							|  |  |  | 	9,  9,  8,  8,  8,  8,  8,  7,  7,  7,  /* 10 - 19 */ | 
					
						
							|  |  |  | 	7,  7,  7,  7,  6,  6,  6,  6,  6,  6,  /* 20 - 29 */ | 
					
						
							|  |  |  | 	6,  6,  6,  6,  6,  6,  6};             /* 30 - 36 */ | 
					
						
							| 
									
										
										
										
											2006-07-09 22:14:42 +00:00
										 |  |  | #elif SIZEOF_LONG == 8
 | 
					
						
							|  |  |  | /* [int(math.floor(math.log(2**64, i))) for i in range(2, 37)] */ | 
					
						
							|  |  |  | static int digitlimit[] = { | 
					
						
							|  |  |  | 	 0,   0, 64, 40, 32, 27, 24, 22, 21, 20,  /*  0 -  9 */ | 
					
						
							|  |  |  | 	19,  18, 17, 17, 16, 16, 16, 15, 15, 15,  /* 10 - 19 */ | 
					
						
							|  |  |  | 	14,  14, 14, 14, 13, 13, 13, 13, 13, 13,  /* 20 - 29 */ | 
					
						
							|  |  |  | 	13,  12, 12, 12, 12, 12, 12};             /* 30 - 36 */ | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #error "Need table for SIZEOF_LONG"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2006-05-23 18:45:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-12-24 10:32:00 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  | **	strtoul | 
					
						
							|  |  |  | **		This is a general purpose routine for converting | 
					
						
							|  |  |  | **		an ascii string to an integer in an arbitrary base. | 
					
						
							|  |  |  | **		Leading white space is ignored.  If 'base' is zero | 
					
						
							|  |  |  | **		it looks for a leading 0, 0x or 0X to tell which | 
					
						
							|  |  |  | **		base.  If these are absent it defaults to 10. | 
					
						
							|  |  |  | **		Base must be 0 or between 2 and 36 (inclusive). | 
					
						
							|  |  |  | **		If 'ptr' is non-NULL it will contain a pointer to | 
					
						
							|  |  |  | **		the end of the scan. | 
					
						
							|  |  |  | **		Errors due to bad pointers will probably result in | 
					
						
							|  |  |  | **		exceptions - we don't check for them. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | unsigned long | 
					
						
							| 
									
										
										
										
											2000-07-22 18:47:25 +00:00
										 |  |  | PyOS_strtoul(register char *str, char **ptr, int base) | 
					
						
							| 
									
										
										
										
											1993-12-24 10:32:00 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-05-23 18:45:30 +00:00
										 |  |  | 	register unsigned long result = 0; /* return value of the function */ | 
					
						
							|  |  |  | 	register int c;	 	/* current input character */ | 
					
						
							|  |  |  | 	register int ovlimit; 	/* required digits to overflow */ | 
					
						
							| 
									
										
										
										
											1993-12-24 10:32:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-05-23 18:45:30 +00:00
										 |  |  | 	/* skip leading white space */ | 
					
						
							|  |  |  | 	while (*str && isspace(Py_CHARMASK(*str))) | 
					
						
							|  |  |  | 		++str; | 
					
						
							| 
									
										
										
										
											1993-12-24 10:32:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-05-23 18:45:30 +00:00
										 |  |  | 	/* check for leading 0 or 0x for auto-base or base 16 */ | 
					
						
							|  |  |  | 	switch (base) { | 
					
						
							|  |  |  | 		case 0:		/* look for leading 0, 0x or 0X */ | 
					
						
							|  |  |  | 			if (*str == '0') { | 
					
						
							|  |  |  | 				++str; | 
					
						
							|  |  |  | 				if (*str == 'x' || *str == 'X') { | 
					
						
							|  |  |  | 					++str; | 
					
						
							|  |  |  | 					base = 16; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					base = 8; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				base = 10; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case 16:	/* skip leading 0x or 0X */ | 
					
						
							|  |  |  | 			if (*str == '0') { | 
					
						
							|  |  |  | 				++str; | 
					
						
							|  |  |  | 				if (*str == 'x' || *str == 'X') | 
					
						
							|  |  |  | 					++str; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											1993-12-24 10:32:00 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-05-23 18:45:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* catch silly bases */ | 
					
						
							|  |  |  | 	if (base < 2 || base > 36) { | 
					
						
							|  |  |  | 		if (ptr) | 
					
						
							|  |  |  | 			*ptr = str; | 
					
						
							|  |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											1993-12-24 10:32:00 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-05-23 18:45:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* skip leading zeroes */ | 
					
						
							|  |  |  | 	while (*str == '0') | 
					
						
							|  |  |  | 		++str; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* base is guaranteed to be in [2, 36] at this point */ | 
					
						
							|  |  |  | 	ovlimit = digitlimit[base]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* do the conversion until non-digit character encountered */ | 
					
						
							| 
									
										
										
										
											2006-05-25 17:34:03 +00:00
										 |  |  | 	while ((c = _PyLong_DigitValue[Py_CHARMASK(*str)]) < base) { | 
					
						
							| 
									
										
										
										
											2006-05-23 18:45:30 +00:00
										 |  |  | 		if (ovlimit > 0) /* no overflow check required */ | 
					
						
							|  |  |  | 			result = result * base + c; | 
					
						
							|  |  |  | 		else { /* requires overflow check */ | 
					
						
							|  |  |  | 			register unsigned long temp_result; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (ovlimit < 0) /* guaranteed overflow */ | 
					
						
							|  |  |  | 				goto overflowed; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* there could be an overflow */ | 
					
						
							|  |  |  | 			/* check overflow just from shifting */ | 
					
						
							|  |  |  | 			if (result > smallmax[base]) | 
					
						
							|  |  |  | 				goto overflowed; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			result *= base; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* check overflow from the digit's value */ | 
					
						
							|  |  |  | 			temp_result = result + c; | 
					
						
							|  |  |  | 			if (temp_result < result) | 
					
						
							|  |  |  | 				goto overflowed; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			result = temp_result; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		++str; | 
					
						
							|  |  |  | 		--ovlimit; | 
					
						
							| 
									
										
										
										
											1997-12-15 17:27:35 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-05-23 18:45:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* set pointer to point to the last character scanned */ | 
					
						
							|  |  |  | 	if (ptr) | 
					
						
							|  |  |  | 		*ptr = str; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return result; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | overflowed: | 
					
						
							|  |  |  | 	if (ptr) { | 
					
						
							|  |  |  | 		/* spool through remaining digit characters */ | 
					
						
							| 
									
										
										
										
											2006-05-25 17:34:03 +00:00
										 |  |  | 		while (_PyLong_DigitValue[Py_CHARMASK(*str)] < base) | 
					
						
							| 
									
										
										
										
											2006-05-23 18:45:30 +00:00
										 |  |  | 			++str; | 
					
						
							|  |  |  | 		*ptr = str; | 
					
						
							| 
									
										
										
										
											1997-12-15 17:27:35 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											1993-12-24 10:32:00 +00:00
										 |  |  | 	errno = ERANGE; | 
					
						
							| 
									
										
										
										
											2006-05-23 18:45:30 +00:00
										 |  |  | 	return (unsigned long)-1; | 
					
						
							| 
									
										
										
										
											1993-12-24 10:32:00 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-27 01:14:53 +00:00
										 |  |  | /* Checking for overflow in PyOS_strtol is a PITA since C doesn't define
 | 
					
						
							|  |  |  |  * anything about what happens when a signed integer operation overflows, | 
					
						
							|  |  |  |  * and some compilers think they're doing you a favor by being "clever" | 
					
						
							|  |  |  |  * then.  Python assumes a 2's-complement representation, so that the bit | 
					
						
							|  |  |  |  * pattern for the largest postive signed long is LONG_MAX, and for | 
					
						
							|  |  |  |  * the smallest negative signed long is LONG_MAX + 1. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-12-24 10:32:00 +00:00
										 |  |  | long | 
					
						
							| 
									
										
										
										
											2000-07-22 18:47:25 +00:00
										 |  |  | PyOS_strtol(char *str, char **ptr, int base) | 
					
						
							| 
									
										
										
										
											1993-12-24 10:32:00 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	long result; | 
					
						
							| 
									
										
										
										
											2006-07-27 01:14:53 +00:00
										 |  |  | 	unsigned long uresult; | 
					
						
							| 
									
										
										
										
											1993-12-24 10:32:00 +00:00
										 |  |  | 	char sign; | 
					
						
							| 
									
										
										
										
											2006-05-23 18:45:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-02-10 17:01:56 +00:00
										 |  |  | 	while (*str && isspace(Py_CHARMASK(*str))) | 
					
						
							| 
									
										
										
										
											1993-12-24 10:32:00 +00:00
										 |  |  | 		str++; | 
					
						
							| 
									
										
										
										
											2006-05-23 18:45:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-12-24 10:32:00 +00:00
										 |  |  | 	sign = *str; | 
					
						
							|  |  |  | 	if (sign == '+' || sign == '-') | 
					
						
							|  |  |  | 		str++; | 
					
						
							| 
									
										
										
										
											2006-05-23 18:45:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-27 01:14:53 +00:00
										 |  |  | 	uresult = PyOS_strtoul(str, ptr, base); | 
					
						
							| 
									
										
										
										
											2006-05-23 18:45:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-27 01:14:53 +00:00
										 |  |  | 	if (uresult <= (unsigned long)LONG_MAX) { | 
					
						
							|  |  |  | 		result = (long)uresult; | 
					
						
							|  |  |  | 		if (sign == '-') | 
					
						
							|  |  |  | 			result = -result; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (sign == '-' && uresult == (unsigned long)LONG_MAX + 1) { | 
					
						
							|  |  |  | 		assert(LONG_MIN == -LONG_MAX-1); | 
					
						
							|  |  |  | 		result = LONG_MIN; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											1993-12-24 10:32:00 +00:00
										 |  |  | 		errno = ERANGE; | 
					
						
							| 
									
										
										
										
											2006-07-27 01:14:53 +00:00
										 |  |  | 		result = LONG_MAX; | 
					
						
							| 
									
										
										
										
											1993-12-24 10:32:00 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return result; | 
					
						
							|  |  |  | } |