From ed2cf4c1d66bcdfbf44c34eb94dd94a0535a9334 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Sun, 8 Jan 2017 03:49:20 +0100 Subject: Add vu-single-colour MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/util.c | 171 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 src/util.c (limited to 'src/util.c') diff --git a/src/util.c b/src/util.c new file mode 100644 index 0000000..2ae3a9f --- /dev/null +++ b/src/util.c @@ -0,0 +1,171 @@ +/* See LICENSE file for copyright and license details. */ +#include "util.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +char *argv0; + +static void +xvprintf(const char *fmt, va_list ap) +{ + if (argv0 && strncmp(fmt, "usage", strlen("usage"))) + fprintf(stderr, "%s: ", argv0); + + vfprintf(stderr, fmt, ap); + + if (fmt[0] && fmt[strlen(fmt)-1] == ':') { + fputc(' ', stderr); + perror(NULL); + } +} + +void +eprintf(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + xvprintf(fmt, ap); + va_end(ap); + + exit(1); +} + +void +enprintf(int status, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + xvprintf(fmt, ap); + va_end(ap); + + exit(status); +} + +void +weprintf(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + xvprintf(fmt, ap); + va_end(ap); +} + + +int +tollu(const char *s, unsigned long long int min, unsigned long long int max, unsigned long long int *out) +{ + char *end; + errno = 0; + if (*s == '-') { + errno = ERANGE; + return -1; + } + if (tolower(*s) == 'x' || *s == '#') + *out = strtoull(s + 1, &end, 16); + else if (*s == '0' && tolower(s[1]) == 'x') + *out = strtoull(s + 2, &end, 16); + else if (*s == '0' && tolower(s[1]) == 'o') + *out = strtoull(s + 2, &end, 8); + else if (*s == '0' && tolower(s[1]) == 'b') + *out = strtoull(s + 2, &end, 2); + else + *out = strtoull(s, &end, 10); + if (errno) + return -1; + if (*end) { + errno = EINVAL; + return -1; + } + if (*out < min || *out > max) { + errno = ERANGE; + return -1; + } + return 0; +} + +int +tolli(const char *s, long long int min, long long int max, long long int *out) +{ + char *end; + int sign = 1; + unsigned long long int inter; + errno = 0; + if (*s == '-') { + s++; + sign = -1; + } + if (tollu(s, 0, ULLONG_MAX, &inter)) + return -1; + if (sign > 0) { + if (max < 0 || inter > (unsigned long long int)max) + goto erange; + *out = (long long int)inter; + if (*out < min) + goto erange; + } else { +#if LLONG_MIN == -LLONG_MAX + if (inter > -LLONG_MIN) + goto erange; +#else + if (inter > (unsigned long long int)LLONG_MAX + 1ULL) + goto erange; +#endif + *out = -(long long int)inter; + if (*out < min || *out > max) + goto erange; + } + return 0; + +erange: + errno = ERANGE; + return -1; +} + + +int +fshut(FILE *fp, const char *fname) +{ + int ret = 0; + + /* fflush() is undefined for input streams by ISO C, + * but not POSIX 2008 if you ignore ISO C overrides. + * Leave it unchecked and rely on the following + * functions to detect errors. + */ + fflush(fp); + + if (ferror(fp) && !ret) { + weprintf("ferror %s:", fname); + ret = 1; + } + + if (fclose(fp) && !ret) { + weprintf("fclose %s:", fname); + ret = 1; + } + + return ret; +} + +void +enfshut(int status, FILE *fp, const char *fname) +{ + if (fshut(fp, fname)) + exit(status); +} + +void +efshut(FILE *fp, const char *fname) +{ + enfshut(1, fp, fname); +} -- cgit v1.2.3-70-g09d2