diff options
-rw-r--r-- | util.c | 168 | ||||
-rw-r--r-- | util.h | 14 |
2 files changed, 178 insertions, 4 deletions
@@ -12,7 +12,7 @@ char *argv0; void -read_ff_header(uint32_t *width, uint32_t *height) +ff_read_header(uint32_t *width, uint32_t *height) { uint32_t hdr[4]; @@ -31,7 +31,7 @@ read_ff_header(uint32_t *width, uint32_t *height) } void -write_ff_header(uint32_t width, uint32_t height) +ff_write_header(uint32_t width, uint32_t height) { uint32_t tmp; @@ -49,3 +49,167 @@ write_ff_header(uint32_t width, uint32_t height) exit(1); } } + +int +parse_mask(const char *s, uint16_t mask[3]) +{ + size_t slen, i; + unsigned int col[3], colfac; + char fmt[] = "%#x%#x%#x"; + + if ((s++)[0] != '#') { + return 1; + } + + slen = strlen(s); + if (slen != 3 && slen != 6 && slen != 12) { + return 1; + } + + fmt[1] = fmt[4] = fmt[7] = ((slen / 3) + '0'); + if (sscanf(s, fmt, col, col + 1, col + 2) != 3) { + return 1; + } + + colfac = (slen == 3) ? UINT16_MAX / 0xf : + (slen == 6) ? UINT16_MAX / 0xff : + UINT16_MAX / 0xffff; + + for (i = 0; i < 3; i++) { + mask[i] = col[i] * colfac; + } + + return 0; +} + +void * +ereallocarray(void *optr, size_t nmemb, size_t size) +{ + void *p; + + if (!(p = reallocarray(optr, nmemb, size))) { + fprintf(stderr, "%s: reallocarray: out of memory\n", argv0); + exit(1); + } + + return p; +} + +long long +estrtonum(const char *numstr, long long minval, long long maxval) +{ + const char *errstr; + long long ll; + + ll = strtonum(numstr, minval, maxval, &errstr); + if (errstr) { + fprintf(stderr, "%s: strtonum %s: %s\n", argv0, numstr, errstr); + exit(1); + } + + return ll; +} + +/* + * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <errno.h> +#include <stdint.h> +#include <stdlib.h> + +/* + * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX + * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW + */ +#define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 4)) + +void * +reallocarray(void *optr, size_t nmemb, size_t size) +{ + if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && + nmemb > 0 && SIZE_MAX / nmemb < size) { + errno = ENOMEM; + return NULL; + } + return realloc(optr, size * nmemb); +} + +/* $OpenBSD: strtonum.c,v 1.7 2013/04/17 18:40:58 tedu Exp $ */ + +/* + * Copyright (c) 2004 Ted Unangst and Todd Miller + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <errno.h> +#include <limits.h> +#include <stdlib.h> + +#define INVALID 1 +#define TOOSMALL 2 +#define TOOLARGE 3 + +long long +strtonum(const char *numstr, long long minval, long long maxval, + const char **errstrp) +{ + long long ll = 0; + int error = 0; + char *ep; + struct errval { + const char *errstr; + int err; + } ev[4] = { + { NULL, 0 }, + { "invalid", EINVAL }, + { "too small", ERANGE }, + { "too large", ERANGE }, + }; + + ev[0].err = errno; + errno = 0; + if (minval > maxval) { + error = INVALID; + } else { + ll = strtoll(numstr, &ep, 10); + if (numstr == ep || *ep != '\0') + error = INVALID; + else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) + error = TOOSMALL; + else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) + error = TOOLARGE; + } + if (errstrp != NULL) + *errstrp = ev[error].errstr; + errno = ev[error].err; + if (error) + ll = 0; + + return (ll); +} @@ -6,5 +6,15 @@ extern char *argv0; #define LEN(x) (sizeof (x) / sizeof *(x)) -void read_ff_header(uint32_t *width, uint32_t *height); -void write_ff_header(uint32_t width, uint32_t height); +void ff_read_header(uint32_t *width, uint32_t *height); +void ff_write_header(uint32_t width, uint32_t height); + +int parse_mask(const char *, uint16_t mask[3]); + +#undef reallocarray +void *reallocarray(void *, size_t, size_t); +void *ereallocarray(void *optr, size_t nmemb, size_t size); + +#undef strtonum +long long strtonum(const char *, long long, long long, const char **); +long long estrtonum(const char *, long long, long long); |