#include <errno.h> /* errno, EINVAL, ERANGE */
#include <limits.h> /* INT_MIN, INT_MAX */
#include <stdio.h> /* printf(), fprintf(), stderr */
#include <stdlib.h> /* strtol() */
#include <string.h> /* strerror() */
/* Convert a string to an int. */
int
str_to_int_strtol(const char *s)
{
char *s_rem;
long l;
int errno_save = errno;
errno = 0;
if (errno == 0) {
/* Number out of range. */
if (l < INT_MIN || l > INT_MAX)
errno = ERANGE;
/* Argument isn't completely made up of decimal digits. */
else if (*s_rem != '\0')
errno = EINVAL;
}
if (errno) {
fprintf(stderr
, "strtol() error: operand \"%s\": %s\n", s
, return 0;
}
errno = errno_save;
return (int)l;
}
/* Convert a string to an int (less robust). */
int
str_to_int_atoi(const char *s)
{
int n;
int errno_save = errno;
errno = 0;
if (errno != 0) {
fprintf(stderr
, "atoi() error: operand \"%s\": %s\n", s
, return 0;
}
errno = errno_save;
return n;
}
int
main(void)
{
const char *s = "123hello";
int n;
fprintf(stderr
, "[====atoi()====]\n"); n = str_to_int_atoi(s);
printf(" n: %d\nerrno set: %s\n\n", n
, errno
!= 0 ? "Yes" : "No");
errno = 0;
fprintf(stderr
, "[===strtol()===]\n"); n = str_to_int_strtol(s);
printf(" n: %d\nerrno set: %s\n\n", n
, errno
!= 0 ? "Yes" : "No");
return 0;
}
I2luY2x1ZGUgPGVycm5vLmg+ICAvKiBlcnJubywgRUlOVkFMLCBFUkFOR0UgKi8KI2luY2x1ZGUgPGxpbWl0cy5oPiAvKiBJTlRfTUlOLCBJTlRfTUFYICovCiNpbmNsdWRlIDxzdGRpby5oPiAgLyogcHJpbnRmKCksIGZwcmludGYoKSwgc3RkZXJyICovCiNpbmNsdWRlIDxzdGRsaWIuaD4gLyogc3RydG9sKCkgKi8KI2luY2x1ZGUgPHN0cmluZy5oPiAvKiBzdHJlcnJvcigpICovCgkKLyogQ29udmVydCBhIHN0cmluZyB0byBhbiBpbnQuICovCmludApzdHJfdG9faW50X3N0cnRvbChjb25zdCBjaGFyICpzKQp7CgljaGFyICpzX3JlbTsKCWxvbmcgbDsKCWludCBlcnJub19zYXZlID0gZXJybm87CgoJZXJybm8gPSAwOwoJbCA9IHN0cnRvbChzLCAmc19yZW0sIDEwKTsKCWlmIChlcnJubyA9PSAwKSB7CgkJLyogTnVtYmVyIG91dCBvZiByYW5nZS4gKi8KCQlpZiAobCA8IElOVF9NSU4gfHwgbCA+IElOVF9NQVgpCgkJCWVycm5vID0gRVJBTkdFOwoKCQkvKiBBcmd1bWVudCBpc24ndCBjb21wbGV0ZWx5IG1hZGUgdXAgb2YgZGVjaW1hbCBkaWdpdHMuICovCgkJZWxzZSBpZiAoKnNfcmVtICE9ICdcMCcpCgkJCWVycm5vID0gRUlOVkFMOwoJfQoJaWYgKGVycm5vKSB7CgkJZnByaW50ZihzdGRlcnIsICJzdHJ0b2woKSBlcnJvcjogb3BlcmFuZCBcIiVzXCI6ICVzXG4iLCBzLAoJCSAgICBzdHJlcnJvcihlcnJubykpOwoJCXJldHVybiAwOwoJfQoKCWVycm5vID0gZXJybm9fc2F2ZTsKCXJldHVybiAoaW50KWw7Cn0KCi8qIENvbnZlcnQgYSBzdHJpbmcgdG8gYW4gaW50IChsZXNzIHJvYnVzdCkuICovCmludApzdHJfdG9faW50X2F0b2koY29uc3QgY2hhciAqcykKewoJaW50IG47CglpbnQgZXJybm9fc2F2ZSA9IGVycm5vOwoKCWVycm5vID0gMDsKCW4gPSBhdG9pKHMpOwoKCWlmIChlcnJubyAhPSAwKSB7CgkJZnByaW50ZihzdGRlcnIsICJhdG9pKCkgZXJyb3I6IG9wZXJhbmQgXCIlc1wiOiAlc1xuIiwgcywKCQkgICAgc3RyZXJyb3IoZXJybm8pKTsKCQlyZXR1cm4gMDsKCX0KCgllcnJubyA9IGVycm5vX3NhdmU7CglyZXR1cm4gbjsKfQoKaW50Cm1haW4odm9pZCkKewoJY29uc3QgY2hhciAqcyA9ICIxMjNoZWxsbyI7CglpbnQgbjsKCiAgICBmcHJpbnRmKHN0ZGVyciwgIls9PT09YXRvaSgpPT09PV1cbiIpOwoJbiA9IHN0cl90b19pbnRfYXRvaShzKTsKCXByaW50ZigiICAgICAgICBuOiAlZFxuZXJybm8gc2V0OiAlc1xuXG4iLCBuLCBlcnJubyAhPSAwID8gIlllcyIgOiAiTm8iKTsKCgllcnJubyA9IDA7CgogICAgZnByaW50ZihzdGRlcnIsICJbPT09c3RydG9sKCk9PT1dXG4iKTsKCW4gPSBzdHJfdG9faW50X3N0cnRvbChzKTsKCXByaW50ZigiICAgICAgICBuOiAlZFxuZXJybm8gc2V0OiAlc1xuXG4iLCBuLCBlcnJubyAhPSAwID8gIlllcyIgOiAiTm8iKTsKCglyZXR1cm4gMDsKfQ==