#include #include #include #include static inline long long strtonum(const char *nptr, long long minval, long long maxval, const char **errstr) { const char *p = nptr; char *endptr; long long result; int saved_errno; if (errstr != NULL) *errstr = NULL; if (nptr == NULL || *nptr == '\0') { if (errstr != NULL) *errstr = "invalid"; errno = EINVAL; return 0; } if (minval > maxval) { if (errstr != NULL) *errstr = "invalid"; errno = EINVAL; return 0; } while (isspace((unsigned char)*p)) p++; saved_errno = errno; errno = 0; result = strtoll(p, &endptr, 10); if (errno == ERANGE) { if (errstr != NULL) { *errstr = (result == LLONG_MIN || result < minval) ? "too small" : "too large"; } errno = ERANGE; return 0; } if (endptr == p) { if (errstr != NULL) *errstr = "invalid"; errno = EINVAL; return 0; } while (isspace((unsigned char)*endptr)) endptr++; if (*endptr != '\0') { if (errstr != NULL) *errstr = "invalid"; errno = EINVAL; return 0; } if (result < minval) { if (errstr != NULL) *errstr = "too small"; errno = ERANGE; return 0; } if (result > maxval) { if (errstr != NULL) *errstr = "too large"; errno = ERANGE; return 0; } if (errstr != NULL) *errstr = NULL; return result; } static inline void *reallocf(void *ptr, size_t size) { void *new_ptr = realloc(ptr, size); if (new_ptr == NULL && size != 0) { free(ptr); } return new_ptr; }