diff options
Diffstat (limited to '')
| -rw-r--r-- | src/util.c | 84 | ||||
| -rw-r--r-- | src/util.h | 106 | ||||
| -rw-r--r-- | src/util/colour.h | 49 | ||||
| -rw-r--r-- | src/util/efflush.h | 12 | ||||
| -rw-r--r-- | src/util/emalloc.h | 23 | ||||
| -rw-r--r-- | src/util/eopen.h | 14 | ||||
| -rw-r--r-- | src/util/eprintf.h | 10 | ||||
| -rw-r--r-- | src/util/fshut.h | 36 | ||||
| -rw-r--r-- | src/util/io.h | 12 | ||||
| -rw-r--r-- | src/util/to.h | 135 |
10 files changed, 320 insertions, 161 deletions
@@ -9,12 +9,16 @@ #include <stdlib.h> #include <string.h> #include <strings.h> +#include <unistd.h> char *argv0; -static void -xvprintf(const char *fmt, va_list ap) +void +weprintf(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + if (argv0 && strncmp(fmt, "usage", strlen("usage"))) fprintf(stderr, "%s: ", argv0); @@ -24,39 +28,7 @@ xvprintf(const char *fmt, va_list ap) 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); } @@ -132,39 +104,17 @@ erange: int -fshut(FILE *fp, const char *fname) +writeall(int fd, void *buf, size_t n) { - 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; + char *buffer = buf; + size_t ptr = 0; + ssize_t r; + while (ptr < n) { + r = write(STDOUT_FILENO, buffer, n); + if (r < 0) + return -1; + buffer += (size_t)ptr; + n -= (size_t)ptr; } - - 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); + return 0; } @@ -1,99 +1,17 @@ /* See LICENSE file for copyright and license details. */ -#include <errno.h> -#include <math.h> -#include <stdio.h> -#include <stdlib.h> - -#define D65_XYY_X 0.312726871026564878786047074755 -#define D65_XYY_Y 0.329023206641284038376227272238 +#include "arg.h" #define ELEMENTSOF(ARRAY) (sizeof(ARRAY) / sizeof(*(ARRAY))) -void eprintf(const char *fmt, ...); -void enprintf(int status, const char *fmt, ...); -void weprintf(const char *fmt, ...); - -int tollu(const char *s, unsigned long long int min, unsigned long long int max, unsigned long long int *out); -int tolli(const char *s, long long int min, long long int max, long long int *out); -#define DEF_STR_TO_INT(FNAME, INTTYPE, INTER_FNAME, INTER_INTTYPE)\ - static inline int\ - FNAME(const char *s, INTTYPE min, INTTYPE max, INTTYPE *out)\ - {\ - INTER_INTTYPE inter;\ - if (INTER_FNAME(s, (INTER_INTTYPE)min, (INTER_INTTYPE)max, &inter))\ - return -1;\ - *out = (INTTYPE)inter;\ - return 0;\ - } -DEF_STR_TO_INT(tolu, unsigned long int, tollu, unsigned long long int) -DEF_STR_TO_INT(tou, unsigned int, tollu, unsigned long long int) -DEF_STR_TO_INT(toli, long int, tolli, long long int) -DEF_STR_TO_INT(toi, int, tolli, long long int) -#undef DEF_STR_TO_INT -#define tozu tolu -#define tozi toli -#define toju tollu -#define toji tolli - -static inline int -tolf(const char *s, double *out) -{ - char *end; - errno = 0; - *out = strtod(s, &end); - if (errno) { - return -1; - } else if (*end) { - errno = EINVAL; - return -1; - } - return 0; -} - -int fshut(FILE *fp, const char *fname); -void enfshut(int status, FILE *fp, const char *fname); -void efshut(FILE *fp, const char *fname); - -static inline double -srgb_encode(double t) -{ - double sign = 1; - if (t < 0) { - t = -t; - sign = -1; - } - t = t <= 0.0031306684425217108 ? 12.92 * t : 1.055 * pow(t, 1 / 2.4) - 0.055; - return t * sign; -} - -static inline double -srgb_decode(double t) -{ - double sign = 1; - if (t < 0) { - t = -t; - sign = -1; - } - t = t <= 0.0031306684425217108 * 12.92 ? t / 12.92 : pow((t + 0.055) / 1.055, 2.4); - return t * sign; -} - -static inline void -ciexyz_to_srgb(double x, double y, double z, double *r, double *g, double *b) -{ -#define MULTIPLY(CX, CY, CZ) ((CX) * x + (CY) * y + (CZ) * z) - *r = MULTIPLY(3.240446254647737500675930277794, -1.537134761820080575134284117667, -0.498530193022728718155178739835); - *g = MULTIPLY(-0.969266606244679751469561779231, 1.876011959788370209167851498933, 0.041556042214430065351304932619); - *b = MULTIPLY(0.055643503564352832235773149705, -0.204026179735960239147729566866, 1.057226567722703292062647051353); -#undef MULTIPLY -} +#define USAGE(SYNOPSIS)\ + static void usage(void)\ + { eprintf("usage: %s%s%s\n", argv0, SYNOPSIS ? " " : "", SYNOPSIS); } -static inline void -srgb_to_ciexyz(double r, double g, double b, double *x, double *y, double *z) -{ -#define MULTIPLY(CR, CG, CB) ((CR) * r + (CG) * g + (CB) * b) - *x = MULTIPLY(0.412457445582367576708548995157, 0.357575865245515878143578447634, 0.180437247826399665973085006954); - *y = MULTIPLY(0.212673370378408277403536885686, 0.715151730491031756287156895269, 0.072174899130559869164791564344); - *z = MULTIPLY(0.019333942761673460208893260415, 0.119191955081838593666354597644, 0.950302838552371742508739771438); -#undef MULTIPLY -} +#include "util/eprintf.h" +#include "util/efflush.h" +#include "util/fshut.h" +#include "util/eopen.h" +#include "util/emalloc.h" +#include "util/to.h" +#include "util/colour.h" +#include "util/io.h" diff --git a/src/util/colour.h b/src/util/colour.h new file mode 100644 index 0000000..ff40841 --- /dev/null +++ b/src/util/colour.h @@ -0,0 +1,49 @@ +/* See LICENSE file for copyright and license details. */ +#include <math.h> + +#define D65_XYY_X 0.312726871026564878786047074755 +#define D65_XYY_Y 0.329023206641284038376227272238 + +static inline double +srgb_encode(double t) +{ + double sign = 1; + if (t < 0) { + t = -t; + sign = -1; + } + t = t <= 0.0031306684425217108 ? 12.92 * t : 1.055 * pow(t, 1 / 2.4) - 0.055; + return t * sign; +} + +static inline double +srgb_decode(double t) +{ + double sign = 1; + if (t < 0) { + t = -t; + sign = -1; + } + t = t <= 0.0031306684425217108 * 12.92 ? t / 12.92 : pow((t + 0.055) / 1.055, 2.4); + return t * sign; +} + +static inline void +ciexyz_to_srgb(double x, double y, double z, double *r, double *g, double *b) +{ +#define MULTIPLY(CX, CY, CZ) ((CX) * x + (CY) * y + (CZ) * z) + *r = MULTIPLY(3.240446254647737500675930277794, -1.537134761820080575134284117667, -0.498530193022728718155178739835); + *g = MULTIPLY(-0.969266606244679751469561779231, 1.876011959788370209167851498933, 0.041556042214430065351304932619); + *b = MULTIPLY(0.055643503564352832235773149705, -0.204026179735960239147729566866, 1.057226567722703292062647051353); +#undef MULTIPLY +} + +static inline void +srgb_to_ciexyz(double r, double g, double b, double *x, double *y, double *z) +{ +#define MULTIPLY(CR, CG, CB) ((CR) * r + (CG) * g + (CB) * b) + *x = MULTIPLY(0.412457445582367576708548995157, 0.357575865245515878143578447634, 0.180437247826399665973085006954); + *y = MULTIPLY(0.212673370378408277403536885686, 0.715151730491031756287156895269, 0.072174899130559869164791564344); + *z = MULTIPLY(0.019333942761673460208893260415, 0.119191955081838593666354597644, 0.950302838552371742508739771438); +#undef MULTIPLY +} diff --git a/src/util/efflush.h b/src/util/efflush.h new file mode 100644 index 0000000..001f2af --- /dev/null +++ b/src/util/efflush.h @@ -0,0 +1,12 @@ +/* See LICENSE file for copyright and license details. */ +#include <stdio.h> + +#define efflush(...) enfflush(1, __VA_ARGS__) + +static inline void +enfflush(int status, FILE *fp, const char *fname) +{ + fflush(fp); + if (ferror(fp)) + enprintf(status, "%s:", fname); +} diff --git a/src/util/emalloc.h b/src/util/emalloc.h new file mode 100644 index 0000000..7c4266e --- /dev/null +++ b/src/util/emalloc.h @@ -0,0 +1,23 @@ +/* See LICENSE file for copyright and license details. */ +#include <stdlib.h> + +#define emalloc(...) enmalloc(1, __VA_ARGS__) +#define ecalloc(...) encalloc(1, __VA_ARGS__) + +static inline void * +enmalloc(int status, size_t n) +{ + void *ptr = malloc(n); + if (!ptr) + enprintf(status, "malloc: out of memory\n"); + return ptr; +} + +static inline void * +encalloc(int status, size_t n, size_t m) +{ + void *ptr = calloc(n, m); + if (!ptr) + enprintf(status, "malloc: out of memory\n"); + return ptr; +} diff --git a/src/util/eopen.h b/src/util/eopen.h new file mode 100644 index 0000000..42e8c5d --- /dev/null +++ b/src/util/eopen.h @@ -0,0 +1,14 @@ +/* See LICENSE file for copyright and license details. */ +#include <fcntl.h> + +#define eopen(...) enopen(1, __VA_ARGS__) +#define enopen(...) xenopen(__VA_ARGS__, 0) + +static inline int +xenopen(int status, const char *path, int flags, int mode, ...) +{ + int fd = open(path, flags, mode); + if (fd < 0) + enprintf(status, "open %s:", path); + return fd; +} diff --git a/src/util/eprintf.h b/src/util/eprintf.h new file mode 100644 index 0000000..a9b342f --- /dev/null +++ b/src/util/eprintf.h @@ -0,0 +1,10 @@ +/* See LICENSE file for copyright and license details. */ +#include <stdlib.h> + +void weprintf(const char *fmt, ...); + +#define eprintf(...)\ + (weprintf(__VA_ARGS__), exit(1)) + +#define enprintf(status, ...)\ + (weprintf(__VA_ARGS__), exit(status)) diff --git a/src/util/fshut.h b/src/util/fshut.h new file mode 100644 index 0000000..4c91179 --- /dev/null +++ b/src/util/fshut.h @@ -0,0 +1,36 @@ +/* See LICENSE file for copyright and license details. */ +#include <stdio.h> + +#define efshut(...) enfshut(1, __VA_ARGS__) + +static inline 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; +} + +static inline void +enfshut(int status, FILE *fp, const char *fname) +{ + if (fshut(fp, fname)) + exit(status); +} diff --git a/src/util/io.h b/src/util/io.h new file mode 100644 index 0000000..25f360c --- /dev/null +++ b/src/util/io.h @@ -0,0 +1,12 @@ +/* See LICENSE file for copyright and license details. */ + +#define ewriteall(...) enwriteall(1, __VA_ARGS__) + +int writeall(int fd, void *buf, size_t n); + +static inline void +enwriteall(int status, int fd, void *buf, size_t n, const char *fname) +{ + if (writeall(fd, buf, n)) + enprintf(status, "write %s:", fname); +} diff --git a/src/util/to.h b/src/util/to.h new file mode 100644 index 0000000..7bb08c7 --- /dev/null +++ b/src/util/to.h @@ -0,0 +1,135 @@ +/* See LICENSE file for copyright and license details. */ +#include <errno.h> +#include <stdlib.h> + +int tollu(const char *s, unsigned long long int min, unsigned long long int max, unsigned long long int *out); +int tolli(const char *s, long long int min, long long int max, long long int *out); +#define DEF_STR_TO_INT(FNAME, INTTYPE, INTER_FNAME, INTER_INTTYPE, PRI)\ + static inline int\ + FNAME(const char *s, INTTYPE min, INTTYPE max, INTTYPE *out)\ + {\ + INTER_INTTYPE inter;\ + if (INTER_FNAME(s, (INTER_INTTYPE)min, (INTER_INTTYPE)max, &inter))\ + return -1;\ + *out = (INTTYPE)inter;\ + return 0;\ + } +DEF_STR_TO_INT(tolu, unsigned long int, tollu, unsigned long long int, "lu") +DEF_STR_TO_INT(tou, unsigned int, tollu, unsigned long long int, "u") +DEF_STR_TO_INT(toli, long int, tolli, long long int, "li") +DEF_STR_TO_INT(toi, int, tolli, long long int, "i") +#undef DEF_STR_TO_INT +#define tozu tolu +#define tozi toli +#define toju tollu +#define toji tolli + +#define DEF_STR_TO_INT(FNAME, TYPE, PRI)\ + static inline TYPE\ + en##FNAME##_flag(int status, int flag, const char *s, TYPE min, TYPE max)\ + {\ + TYPE ret = 0;\ + if (!FNAME(s, min, max, &ret))\ + enprintf(status,\ + "argument of -%c must be an integer in [%"PRI", %"PRI"]\n",\ + flag, min, max);\ + return ret;\ + }\ + \ + static inline TYPE\ + e##FNAME##_flag(int flag, const char *s, TYPE min, TYPE max)\ + {\ + return en##FNAME##_flag(1, flag, s, min, max);\ + }\ + \ + static inline TYPE\ + en##FNAME##_arg(int status, const char *name, const char *s, TYPE min, TYPE max)\ + {\ + TYPE ret = 0;\ + if (!FNAME(s, min, max, &ret))\ + enprintf(status,\ + "%s must be an integer in [%"PRI", %"PRI"]\n",\ + name, min, max);\ + return ret;\ + }\ + \ + static inline TYPE\ + e##FNAME##_arg(const char *name, const char *s, TYPE min, TYPE max)\ + {\ + return en##FNAME##_arg(1, name, s, min, max);\ + } +DEF_STR_TO_INT(tollu, unsigned long long int, "llu") +DEF_STR_TO_INT(tolu, unsigned long int, "lu") +DEF_STR_TO_INT(tou, unsigned int, "u") +DEF_STR_TO_INT(tolli, long long int, "lli") +DEF_STR_TO_INT(toli, long int, "li") +DEF_STR_TO_INT(toi, int, "i") +#undef DEF_STR_TO_INT + +#define etozu_flag etolu_flag +#define etozi_flag etoli_flag +#define etoju_flag etollu_flag +#define etoji_flag etolli_flag +#define entozu_flag entolu_flag +#define entozi_flag entoli_flag +#define entoju_flag entollu_flag +#define entoji_flag entolli_flag + +#define etozu_arg etolu_arg +#define etozi_arg etoli_arg +#define etoju_arg etollu_arg +#define etoji_arg etolli_arg +#define entozu_arg entolu_arg +#define entozi_arg entoli_arg +#define entoju_arg entollu_arg +#define entoji_arg entolli_arg + +#define DEF_STR_TO_FLOAT(FNAME, TYPE, FUN)\ + static inline int\ + FNAME(const char *s, TYPE *out)\ + {\ + char *end;\ + errno = 0;\ + *out = FUN(s, &end);\ + if (errno) {\ + return -1;\ + } else if (*end) {\ + errno = EINVAL;\ + return -1;\ + }\ + return 0;\ + }\ + \ + static inline TYPE\ + en##FNAME##_flag(int status, int flag, const char *s)\ + {\ + TYPE ret = 0;\ + if (!FNAME(s, &ret))\ + enprintf(status, "argument of -%c must be floating-point value\n", flag);\ + return ret;\ + }\ + \ + static inline TYPE\ + e##FNAME##_flag(int flag, const char *s)\ + {\ + return en##FNAME##_flag(1, flag, s);\ + }\ + \ + static inline TYPE\ + en##FNAME##_arg(int status, const char *name, const char *s)\ + {\ + TYPE ret = 0;\ + if (!FNAME(s, &ret))\ + enprintf(status, "%s must be floating-point value\n", name);\ + return ret;\ + }\ + \ + static inline TYPE\ + e##FNAME##_arg(const char *name, const char *s)\ + {\ + return en##FNAME##_arg(1, name, s);\ + } +DEF_STR_TO_FLOAT(tof, float, strtof) +DEF_STR_TO_FLOAT(tolf, double, strtod) +DEF_STR_TO_FLOAT(tollf, long double, strtold) +#undef DEF_STR_TO_FLOAT |
