diff --git a/util.c b/util.c index 5bd7d59..d6a6be9 100644 --- a/util.c +++ b/util.c @@ -10,7 +10,91 @@ * Dedication along with this software. If not, see * . */ +/* srand48 visibility for GLIBC */ +#if !defined(__OpenBSD__) +#define _DEFAULT_SOURCE +#endif + +#include +#include +#include #include +#include + +#include "util.h" + +void +err(int eval, const char *fmt, ...) +{ + va_list ap; + int saved_errno; + + saved_errno = errno; + va_start(ap, fmt); + fprintf(stderr, "%s: ", xgetprogname()); + if (fmt != NULL) { + vfprintf(stderr, fmt, ap); + fprintf(stderr, ": "); + } + fprintf(stderr, "%s\n", strerror(saved_errno)); + va_end(ap); + + exit(eval); +} + +void +errx(int eval, const char *fmt, ...) +{ + va_list ap; + int saved_errno; + + saved_errno = errno; + va_start(ap, fmt); + if (fmt != NULL) { + fprintf(stderr, "%s: ", xgetprogname()); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + } + va_end(ap); + + exit(eval); +} + +long double +parse_double(const char *nptr) +{ + char *end; + long double v; + + errno = 0; + v = strtold(nptr, &end); + if (nptr == end || *end != '\0' || (v == 0 && errno == EINVAL)) + errx(1, "invalid number: %s", nptr); + if (errno == ERANGE) + errx(1, "number out of range: %s", nptr); + + return v; +} + +long long +parse_integer(const char *nptr, long long minval, long long maxval) +{ + char *end; + long long v; + + errno = 0; + v = strtoll(nptr, &end, 10); + if (nptr == end || *end != '\0' || (v == 0 && errno == EINVAL)) + errx(1, "invalid number: %s", nptr); + if (v == 0 && errno == ERANGE) + errx(1, "number out of range: %s", nptr); + if (v < minval) + errx(1, "number too low: %s", nptr); + if (v > maxval) + errx(1, "number too high: %s", nptr); + + return v; +} const char * xgetprogname(void) diff --git a/util.h b/util.h index 3bb406d..3ab3df1 100644 --- a/util.h +++ b/util.h @@ -12,5 +12,9 @@ */ #define nelems(_a) (sizeof((_a)) / sizeof((_a)[0])) +void err(int, const char *, ...); +void errx(int, const char *, ...); +long double parse_double(const char *); +long long parse_integer(const char *, long long, long long); const char * xgetprogname(void); void xsrand48(long);