| 33 | #define TOOLARGE 3 |
| 34 | |
| 35 | long long |
| 36 | strtonum(const char *numstr, long long minval, long long maxval, |
| 37 | const char **errstrp) |
| 38 | { |
| 39 | long long ll = 0; |
| 40 | int error = 0; |
| 41 | char *ep; |
| 42 | struct errval { |
| 43 | const char *errstr; |
| 44 | int err; |
| 45 | } ev[4] = { |
| 46 | { NULL, 0 }, |
| 47 | { "invalid", EINVAL }, |
| 48 | { "too small", ERANGE }, |
| 49 | { "too large", ERANGE }, |
| 50 | }; |
| 51 | |
| 52 | ev[0].err = errno; |
| 53 | errno = 0; |
| 54 | if (minval > maxval) { |
| 55 | error = INVALID; |
| 56 | } else { |
| 57 | ll = strtoll(numstr, &ep, 10); |
| 58 | if (errno == EINVAL || numstr == ep || *ep != '\0') |
| 59 | error = INVALID; |
| 60 | else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) |
| 61 | error = TOOSMALL; |
| 62 | else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) |
| 63 | error = TOOLARGE; |
| 64 | } |
| 65 | if (errstrp != NULL) |
| 66 | *errstrp = ev[error].errstr; |
| 67 | errno = ev[error].err; |
| 68 | if (error) |
| 69 | ll = 0; |
| 70 | |
| 71 | return (ll); |
| 72 | } |
no outgoing calls
no test coverage detected