symbian-qemu-0.9.1-12/python-2.6.1/Python/mystrtoul.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 
       
     2 #include "Python.h"
       
     3 
       
     4 #if defined(__sgi) && defined(WITH_THREAD) && !defined(_SGI_MP_SOURCE)
       
     5 #define _SGI_MP_SOURCE
       
     6 #endif
       
     7 
       
     8 /* strtol and strtoul, renamed to avoid conflicts */
       
     9 
       
    10 
       
    11 #include <ctype.h>
       
    12 #ifdef HAVE_ERRNO_H
       
    13 #include <errno.h>
       
    14 #endif
       
    15 
       
    16 /* Static overflow check values for bases 2 through 36.
       
    17  * smallmax[base] is the largest unsigned long i such that
       
    18  * i * base doesn't overflow unsigned long.
       
    19  */
       
    20 static unsigned long smallmax[] = {
       
    21 	0, /* bases 0 and 1 are invalid */
       
    22 	0,
       
    23 	ULONG_MAX / 2,
       
    24 	ULONG_MAX / 3,
       
    25 	ULONG_MAX / 4,
       
    26 	ULONG_MAX / 5,
       
    27 	ULONG_MAX / 6,
       
    28 	ULONG_MAX / 7,
       
    29 	ULONG_MAX / 8,
       
    30 	ULONG_MAX / 9,
       
    31 	ULONG_MAX / 10,
       
    32 	ULONG_MAX / 11,
       
    33 	ULONG_MAX / 12,
       
    34 	ULONG_MAX / 13,
       
    35 	ULONG_MAX / 14,
       
    36 	ULONG_MAX / 15,
       
    37 	ULONG_MAX / 16,
       
    38 	ULONG_MAX / 17,
       
    39 	ULONG_MAX / 18,
       
    40 	ULONG_MAX / 19,
       
    41 	ULONG_MAX / 20,
       
    42 	ULONG_MAX / 21,
       
    43 	ULONG_MAX / 22,
       
    44 	ULONG_MAX / 23,
       
    45 	ULONG_MAX / 24,
       
    46 	ULONG_MAX / 25,
       
    47 	ULONG_MAX / 26,
       
    48 	ULONG_MAX / 27,
       
    49 	ULONG_MAX / 28,
       
    50 	ULONG_MAX / 29,
       
    51 	ULONG_MAX / 30,
       
    52 	ULONG_MAX / 31,
       
    53 	ULONG_MAX / 32,
       
    54 	ULONG_MAX / 33,
       
    55 	ULONG_MAX / 34,
       
    56 	ULONG_MAX / 35,
       
    57 	ULONG_MAX / 36,
       
    58 };
       
    59 
       
    60 /* maximum digits that can't ever overflow for bases 2 through 36,
       
    61  * calculated by [int(math.floor(math.log(2**32, i))) for i in range(2, 37)].
       
    62  * Note that this is pessimistic if sizeof(long) > 4.
       
    63  */
       
    64 #if SIZEOF_LONG == 4
       
    65 static int digitlimit[] = {
       
    66 	0,  0, 32, 20, 16, 13, 12, 11, 10, 10,  /*  0 -  9 */
       
    67 	9,  9,  8,  8,  8,  8,  8,  7,  7,  7,  /* 10 - 19 */
       
    68 	7,  7,  7,  7,  6,  6,  6,  6,  6,  6,  /* 20 - 29 */
       
    69 	6,  6,  6,  6,  6,  6,  6};             /* 30 - 36 */
       
    70 #elif SIZEOF_LONG == 8
       
    71 /* [int(math.floor(math.log(2**64, i))) for i in range(2, 37)] */
       
    72 static int digitlimit[] = {
       
    73 	 0,   0, 64, 40, 32, 27, 24, 22, 21, 20,  /*  0 -  9 */
       
    74 	19,  18, 17, 17, 16, 16, 16, 15, 15, 15,  /* 10 - 19 */
       
    75 	14,  14, 14, 14, 13, 13, 13, 13, 13, 13,  /* 20 - 29 */
       
    76 	13,  12, 12, 12, 12, 12, 12};             /* 30 - 36 */
       
    77 #else
       
    78 #error "Need table for SIZEOF_LONG"
       
    79 #endif
       
    80 
       
    81 /*
       
    82 **	strtoul
       
    83 **		This is a general purpose routine for converting
       
    84 **		an ascii string to an integer in an arbitrary base.
       
    85 **		Leading white space is ignored.  If 'base' is zero
       
    86 **		it looks for a leading 0, 0b, 0B, 0o, 0O, 0x or 0X
       
    87 **		to tell which base.  If these are absent it defaults
       
    88 **		to 10. Base must be 0 or between 2 and 36 (inclusive).
       
    89 **		If 'ptr' is non-NULL it will contain a pointer to
       
    90 **		the end of the scan.
       
    91 **		Errors due to bad pointers will probably result in
       
    92 **		exceptions - we don't check for them.
       
    93 */
       
    94 unsigned long
       
    95 PyOS_strtoul(register char *str, char **ptr, int base)
       
    96 {
       
    97 	register unsigned long result = 0; /* return value of the function */
       
    98 	register int c;	 	/* current input character */
       
    99 	register int ovlimit; 	/* required digits to overflow */
       
   100 
       
   101 	/* skip leading white space */
       
   102 	while (*str && isspace(Py_CHARMASK(*str)))
       
   103 		++str;
       
   104 
       
   105 	/* check for leading 0 or 0x for auto-base or base 16 */
       
   106 	switch (base) {
       
   107 	case 0:		/* look for leading 0, 0b, 0o or 0x */
       
   108 		if (*str == '0') {
       
   109 			++str;
       
   110 			if (*str == 'x' || *str == 'X') {
       
   111 				/* there must be at least one digit after 0x */
       
   112 				if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 16) {
       
   113 					if (ptr)
       
   114 						*ptr = str;
       
   115 					return 0;
       
   116 				}
       
   117 				++str;
       
   118 				base = 16;
       
   119 			} else if (*str == 'o' || *str == 'O') {
       
   120 				/* there must be at least one digit after 0o */
       
   121 				if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 8) {
       
   122 					if (ptr)
       
   123 						*ptr = str;
       
   124 					return 0;
       
   125 				}
       
   126 				++str;
       
   127 				base = 8;
       
   128 			} else if (*str == 'b' || *str == 'B') {
       
   129 				/* there must be at least one digit after 0b */
       
   130 				if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 2) {
       
   131 					if (ptr)
       
   132 						*ptr = str;
       
   133 					return 0;
       
   134 				}
       
   135 				++str;
       
   136 				base = 2;
       
   137 			} else {
       
   138 				base = 8;
       
   139 			}
       
   140 		}
       
   141 		else
       
   142 			base = 10;
       
   143 		break;
       
   144 
       
   145 	case 2:	/* skip leading 0b or 0B */
       
   146 		if (*str == '0') {
       
   147 			++str;
       
   148 			if (*str == 'b' || *str == 'B') {
       
   149 				/* there must be at least one digit after 0b */
       
   150 				if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 2) {
       
   151 					if (ptr)
       
   152 						*ptr = str;
       
   153 					return 0;
       
   154 				}
       
   155 				++str;
       
   156 			}
       
   157 		}
       
   158 		break;
       
   159 
       
   160 	case 8:	/* skip leading 0o or 0O */
       
   161 		if (*str == '0') {
       
   162 			++str;
       
   163 			if (*str == 'o' || *str == 'O') {
       
   164 				/* there must be at least one digit after 0o */
       
   165 				if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 8) {
       
   166 					if (ptr)
       
   167 						*ptr = str;
       
   168 					return 0;
       
   169 				}
       
   170 				++str;
       
   171 			}
       
   172 		}
       
   173 		break;
       
   174 
       
   175 	case 16:	/* skip leading 0x or 0X */
       
   176 		if (*str == '0') {
       
   177 			++str;
       
   178 			if (*str == 'x' || *str == 'X') {
       
   179 				/* there must be at least one digit after 0x */
       
   180 				if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 16) {
       
   181 					if (ptr)
       
   182 						*ptr = str;
       
   183 					return 0;
       
   184 				}
       
   185 				++str;
       
   186 			}
       
   187 		}
       
   188 		break;
       
   189 	}
       
   190 
       
   191 	/* catch silly bases */
       
   192 	if (base < 2 || base > 36) {
       
   193 		if (ptr)
       
   194 			*ptr = str;
       
   195 		return 0;
       
   196 	}
       
   197 
       
   198 	/* skip leading zeroes */
       
   199 	while (*str == '0')
       
   200 		++str;
       
   201 
       
   202 	/* base is guaranteed to be in [2, 36] at this point */
       
   203 	ovlimit = digitlimit[base];
       
   204 
       
   205 	/* do the conversion until non-digit character encountered */
       
   206 	while ((c = _PyLong_DigitValue[Py_CHARMASK(*str)]) < base) {
       
   207 		if (ovlimit > 0) /* no overflow check required */
       
   208 			result = result * base + c;
       
   209 		else { /* requires overflow check */
       
   210 			register unsigned long temp_result;
       
   211 
       
   212 			if (ovlimit < 0) /* guaranteed overflow */
       
   213 				goto overflowed;
       
   214 
       
   215 			/* there could be an overflow */
       
   216 			/* check overflow just from shifting */
       
   217 			if (result > smallmax[base])
       
   218 				goto overflowed;
       
   219 
       
   220 			result *= base;
       
   221 
       
   222 			/* check overflow from the digit's value */
       
   223 			temp_result = result + c;
       
   224 			if (temp_result < result)
       
   225 				goto overflowed;
       
   226 
       
   227 			result = temp_result;
       
   228 		}
       
   229 
       
   230 		++str;
       
   231 		--ovlimit;
       
   232 	}
       
   233 
       
   234 	/* set pointer to point to the last character scanned */
       
   235 	if (ptr)
       
   236 		*ptr = str;
       
   237 
       
   238 	return result;
       
   239 
       
   240 overflowed:
       
   241 	if (ptr) {
       
   242 		/* spool through remaining digit characters */
       
   243 		while (_PyLong_DigitValue[Py_CHARMASK(*str)] < base)
       
   244 			++str;
       
   245 		*ptr = str;
       
   246 	}
       
   247 	errno = ERANGE;
       
   248 	return (unsigned long)-1;
       
   249 }
       
   250 
       
   251 /* Checking for overflow in PyOS_strtol is a PITA; see comments
       
   252  * about PY_ABS_LONG_MIN in longobject.c.
       
   253  */
       
   254 #define PY_ABS_LONG_MIN		(0-(unsigned long)LONG_MIN)
       
   255 
       
   256 long
       
   257 PyOS_strtol(char *str, char **ptr, int base)
       
   258 {
       
   259 	long result;
       
   260 	unsigned long uresult;
       
   261 	char sign;
       
   262 
       
   263 	while (*str && isspace(Py_CHARMASK(*str)))
       
   264 		str++;
       
   265 
       
   266 	sign = *str;
       
   267 	if (sign == '+' || sign == '-')
       
   268 		str++;
       
   269 
       
   270 	uresult = PyOS_strtoul(str, ptr, base);
       
   271 
       
   272 	if (uresult <= (unsigned long)LONG_MAX) {
       
   273 		result = (long)uresult;
       
   274 		if (sign == '-')
       
   275 			result = -result;
       
   276 	}
       
   277 	else if (sign == '-' && uresult == PY_ABS_LONG_MIN) {
       
   278 		result = LONG_MIN;
       
   279 	}
       
   280 	else {
       
   281 		errno = ERANGE;
       
   282 		result = LONG_MAX;
       
   283 	}
       
   284 	return result;
       
   285 }