diff options
| author | Mattias Andrée <maandree@kth.se> | 2017-01-08 03:49:20 +0100 |
|---|---|---|
| committer | Mattias Andrée <maandree@kth.se> | 2017-01-08 03:49:20 +0100 |
| commit | ed2cf4c1d66bcdfbf44c34eb94dd94a0535a9334 (patch) | |
| tree | bcd5c310dcd43474e945dbcd44a3fd0cc6f8bb68 /src/util.c | |
| parent | Add license (diff) | |
| download | blind-ed2cf4c1d66bcdfbf44c34eb94dd94a0535a9334.tar.gz blind-ed2cf4c1d66bcdfbf44c34eb94dd94a0535a9334.tar.bz2 blind-ed2cf4c1d66bcdfbf44c34eb94dd94a0535a9334.tar.xz | |
Add vu-single-colour
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'src/util.c')
| -rw-r--r-- | src/util.c | 171 |
1 files changed, 171 insertions, 0 deletions
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 <ctype.h> +#include <errno.h> +#include <limits.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> + +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); +} |
