| 50 | '\177') |
| 51 | |
| 52 | char *str2int(register const char *src, register int radix, long int lower, |
| 53 | long int upper, long int *val) |
| 54 | { |
| 55 | int sign; /* is number negative (+1) or positive (-1) */ |
| 56 | int n; /* number of digits yet to be converted */ |
| 57 | long limit; /* "largest" possible valid input */ |
| 58 | long scale; /* the amount to multiply next digit by */ |
| 59 | long sofar; /* the running value */ |
| 60 | register int d; /* (negative of) next digit */ |
| 61 | char *start; |
| 62 | int digits[32]; /* Room for numbers */ |
| 63 | |
| 64 | /* Make sure *val is sensible in case of error */ |
| 65 | |
| 66 | *val = 0; |
| 67 | |
| 68 | /* Check that the radix is in the range 2..36 */ |
| 69 | |
| 70 | #ifndef DBUG_OFF |
| 71 | if (radix < 2 || radix > 36) { |
| 72 | errno=EDOM; |
| 73 | return NullS; |
| 74 | } |
| 75 | #endif |
| 76 | |
| 77 | /* The basic problem is: how do we handle the conversion of |
| 78 | a number without resorting to machine-specific code to |
| 79 | check for overflow? Obviously, we have to ensure that |
| 80 | no calculation can overflow. We are guaranteed that the |
| 81 | "lower" and "upper" arguments are valid machine integers. |
| 82 | On sign-and-magnitude, twos-complement, and ones-complement |
| 83 | machines all, if +|n| is representable, so is -|n|, but on |
| 84 | twos complement machines the converse is not true. So the |
| 85 | "maximum" representable number has a negative representative. |
| 86 | Limit is set to min(-|lower|,-|upper|); this is the "largest" |
| 87 | number we are concerned with. */ |
| 88 | |
| 89 | /* Calculate Limit using Scale as a scratch variable */ |
| 90 | |
| 91 | if ((limit = lower) > 0) limit = -limit; |
| 92 | if ((scale = upper) > 0) scale = -scale; |
| 93 | if (scale < limit) limit = scale; |
| 94 | |
| 95 | /* Skip leading spaces and check for a sign. |
| 96 | Note: because on a 2s complement machine MinLong is a valid |
| 97 | integer but |MinLong| is not, we have to keep the current |
| 98 | converted value (and the scale!) as *negative* numbers, |
| 99 | so the sign is the opposite of what you might expect. |
| 100 | */ |
| 101 | while (my_isspace(&my_charset_latin1,*src)) src++; |
| 102 | sign = -1; |
| 103 | if (*src == '+') src++; else |
| 104 | if (*src == '-') src++, sign = 1; |
| 105 | |
| 106 | /* Skip leading zeros so that we never compute a power of radix |
| 107 | in scale that we won't have a need for. Otherwise sticking |
| 108 | enough 0s in front of a number could cause the multiplication |
| 109 | to overflow when it neededn't. |
no test coverage detected