aboutsummaryrefslogtreecommitdiffstats
path: root/src/util
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/util.c84
-rw-r--r--src/util.h106
-rw-r--r--src/util/colour.h49
-rw-r--r--src/util/efflush.h12
-rw-r--r--src/util/emalloc.h23
-rw-r--r--src/util/eopen.h14
-rw-r--r--src/util/eprintf.h10
-rw-r--r--src/util/fshut.h36
-rw-r--r--src/util/io.h12
-rw-r--r--src/util/to.h135
10 files changed, 320 insertions, 161 deletions
diff --git a/src/util.c b/src/util.c
index 215a961..40f60e1 100644
--- a/src/util.c
+++ b/src/util.c
@@ -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;
}
diff --git a/src/util.h b/src/util.h
index fe83c14..d797356 100644
--- a/src/util.h
+++ b/src/util.h
@@ -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