aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/blackbody.c9
-rw-r--r--src/macros.h57
-rw-r--r--src/parse_10deg.c12
-rw-r--r--src/radharc.c5
-rw-r--r--src/settings.c38
-rw-r--r--src/state.c85
6 files changed, 125 insertions, 81 deletions
diff --git a/src/blackbody.c b/src/blackbody.c
index acd9afc..26ea52e 100644
--- a/src/blackbody.c
+++ b/src/blackbody.c
@@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "blackbody.h"
-#include <unistd.h>
+#include "macros.h"
#include <math.h>
#include <errno.h>
@@ -120,14 +120,13 @@ get_colour(int fd, long int temp, double *r, double *g, double *b)
* unencodeable. */
if (temp > HIGHEST) temp = HIGHEST;
/* Things do not glow below 1000 K. Yes, fire is hot! */
- if (temp < LOWEST) return errno = EDOM, -1;
+ if (temp < LOWEST) t ((errno = EDOM));
/* Read table. */
offset = ((off_t)temp - LOWEST) / DELTA;
offset *= (off_t)(5 * sizeof(double));
errno = 0;
- if (pread(fd, values, sizeof(values), offset) < (ssize_t)sizeof(values))
- return -1;
+ xpread(fd, values, sizeof(values), offset);
/* Get colour. */
if (temp % DELTA)
@@ -144,5 +143,7 @@ get_colour(int fd, long int temp, double *r, double *g, double *b)
*b = *b > 0.0 ? *b : 0.0;
return 0;
+fail:
+ return -1;
}
diff --git a/src/macros.h b/src/macros.h
new file mode 100644
index 0000000..298a41a
--- /dev/null
+++ b/src/macros.h
@@ -0,0 +1,57 @@
+/**
+ * Copyright © 2016 Mattias Andrée <maandree@member.fsf.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+
+
+#define try(...) do { if (!(__VA_ARGS__)) goto fail; } while (0)
+#define t(...) do { if (__VA_ARGS__) goto fail; } while (0)
+#define CLEANUP(...) do { int cleanup__ = errno; __VA_ARGS__; errno = cleanup__; } while (0)
+
+#define xstrdup(outp, ...) \
+do { \
+ const char *xstrdup__ = (__VA_ARGS__); \
+ if (xstrdup__) \
+ try (*(outp) = strdup(xstrdup__)); \
+ else \
+ *(outp) = NULL; \
+} while (0)
+
+#define xpread(fd, buf, len, off) t (pread(fd, buf, len, off) < (ssize_t)(len))
+#define xpwrite(fd, buf, len, off) t (pwrite(fd, buf, len, off) < (ssize_t)(len))
+#define xread(fd, buf, len) t (read(fd, buf, len) < (ssize_t)(len))
+#define xwrite(fd, buf, len) t (write(fd, buf, len) < (ssize_t)(len))
+
+#define xcalloc(outp, num) try (*(outp) = calloc(num, sizeof(**(outp))))
+#define xmalloc(outp, num) try (*(outp) = malloc((num) * sizeof(**(outp))))
+#define xrealloc(outp, num) \
+do { \
+ size_t n__ = (num); \
+ void *new__ = realloc(*(outp), n__ * sizeof(**(outp))); \
+ t (n__ && !new__); \
+ *(outp) = new__; \
+} while (0)
+
+#define SHRINK(outp, num) \
+do { \
+ void *new__ = realloc(*(outp), (num) * sizeof(**(outp))); \
+ if (new__) *(outp) = new__; \
+} while (0)
+
diff --git a/src/parse_10deg.c b/src/parse_10deg.c
index 245814b..1ef6947 100644
--- a/src/parse_10deg.c
+++ b/src/parse_10deg.c
@@ -15,8 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "haiku.h"
-#include <stdio.h>
-#include <unistd.h>
+#include "macros.h"
#include <math.h>
#include <sys/stat.h>
@@ -54,13 +53,10 @@ int main(int argc, char *argv[])
while (fscanf(stdin, "%lf %lf\n", xyrgb + 0, xyrgb + 1) == 2) {
ciexyy_to_srgb(xyrgb[0], xyrgb[1], 1.0, xyrgb + 2, xyrgb + 3, xyrgb + 4);
- if (write(1, xyrgb, sizeof(xyrgb)) < (ssize_t)sizeof(xyrgb))
- goto fail;
+ xwrite(STDOUT_FILENO, xyrgb, sizeof(xyrgb));
}
- if (write(1, xyrgb, sizeof(xyrgb)) < (ssize_t)sizeof(xyrgb)) /* sugar */
- goto fail;
- if (fstat(1, &attr))
- goto fail;
+ xwrite(STDOUT_FILENO, xyrgb, sizeof(xyrgb)); /* sugar */
+ t (fstat(STDOUT_FILENO, &attr));
if ((size_t)(attr.st_size) != (EXPECTED_ELEMENTS + 1) * 5 * sizeof(double))
return 1;
diff --git a/src/radharc.c b/src/radharc.c
index 86f21df..292c0b6 100644
--- a/src/radharc.c
+++ b/src/radharc.c
@@ -16,10 +16,7 @@
*/
#include "state.h"
#include "haiku.h"
-#include <stdio.h>
-#include <stdlib.h>
-
-#define t(...) do { if (__VA_ARGS__) goto fail; } while (0)
+#include "macros.h"
/**
diff --git a/src/settings.c b/src/settings.c
index 6ee5130..e05c98c 100644
--- a/src/settings.c
+++ b/src/settings.c
@@ -17,9 +17,7 @@
#include "settings.h"
#include "arg.h"
#include "haiku.h"
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
+#include "macros.h"
#include <ctype.h>
#include <errno.h>
#include <math.h>
@@ -68,15 +66,17 @@ parse_temperature(const char *str, long int *temp, int *direction, int lower)
switch (*str) {
case '-': dir = -1; break;
case '+': dir = +1; break;
+ default: break;
}
str += !!dir;
- if (dir && !direction) return -1;
- else if (dir) *direction = dir;
- if (!isdigit(*str)) return -1;
+ t (dir && !direction);
+ if (dir) *direction = dir;
+ t (!isdigit(*str));
*temp = (errno = 0, strtol)(str, &end, 10);
- if ((errno && !((errno == ERANGE) && (*temp == LONG_MAX))) || *end || (*temp < lower))
- return -1;
+ t ((errno && !((errno == ERANGE) && (*temp == LONG_MAX))) || *end || (*temp < lower));
return 0;
+fail:
+ return -1;
}
@@ -94,16 +94,15 @@ parse_timespec(const char *str, struct timespec *ts)
memset(ts, 0, sizeof(*ts));
/* Parse seconds. */
- if (!isdigit(*str))
- return -1;
+ t (!isdigit(*str));
while (isdigit(*str)) {
ts->tv_sec *= 10;
ts->tv_sec += *str++ & 15;
}
/* End? */
- if (!*str) return 0;
- if (*str != '.') return -1;
+ if (!*str) return 0;
+ t (*str != '.');
/* Parse nanoseconds.*/
for (; (points++ < 9) && isdigit(*str); str++) {
@@ -111,7 +110,7 @@ parse_timespec(const char *str, struct timespec *ts)
ts->tv_nsec += *str++ & 15;
}
if (points == 9) {
- if (!isdigit(*str)) return -1;
+ t (!isdigit(*str));
if (*str++ >= '5') {
ts->tv_nsec += 1;
if (ts->tv_nsec == 1000000000L)
@@ -119,10 +118,12 @@ parse_timespec(const char *str, struct timespec *ts)
}
}
while (isdigit(*str)) str++;
- if (*str) return -1;
+ t (*str);
/* End! */
return 0;
+fail:
+ return -1;
}
@@ -208,11 +209,10 @@ parse_command_line(int argc, char *argv[], struct settings *settings)
case 'd': c++; /* Fall though. */
case 'e': c++; /* Fall though. */
case 'm': c++;
-#define REALLOC(VAR, N) !(VAR = realloc(VAR, (N) * sizeof(*VAR)))
PLUS(settings->monitors_n = 0, free(settings->monitors_id), free(settings->monitors_arg));
settings->monitors_n++;
- if (REALLOC(settings->monitors_id, settings->monitors_n)) goto fail;
- if (REALLOC(settings->monitors_arg, settings->monitors_n)) goto fail;
+ xrealloc(&(settings->monitors_id), settings->monitors_n);
+ xrealloc(&(settings->monitors_arg), settings->monitors_n);
settings->monitors_id[settings->monitors_n - 1] = ARGF();
settings->monitors_arg[settings->monitors_n - 1] = (c == 3 ? 'm' : c == 2 ? 'e' : 'd'), c = 0;
break;
@@ -297,8 +297,8 @@ unmarshal_settings(char *buffer, struct settings **settings)
UNMARSHAL(sizeof(s_), &s_);
if (s_.monitors_n) {
- if (!(*s = s_, s->monitors_id = malloc(s_.monitors_n * sizeof(char*)))) goto fail;
- if (!(*s = s_, s->monitors_arg = malloc(s_.monitors_n * sizeof(char)))) goto fail;
+ try (*s = s_, s->monitors_id = malloc(s_.monitors_n * sizeof(char*)));
+ try (*s = s_, s->monitors_arg = malloc(s_.monitors_n * sizeof(char)));
}
s->hookpath = buf;
diff --git a/src/state.c b/src/state.c
index 784b429..5640045 100644
--- a/src/state.c
+++ b/src/state.c
@@ -16,19 +16,13 @@
*/
#include "state.h"
#include "solar.h"
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
+#include "macros.h"
#include <errno.h>
#include <limits.h>
#include <libgamma.h>
-#define try(...) do { if (!(__VA_ARGS__)) goto fail; } while (0)
-#define t(...) do { if (__VA_ARGS__) goto fail; } while (0)
-
-
/**
* The name of the process.
@@ -121,10 +115,10 @@ displayenvcmp(const void *a_, const void *b_)
static char *
escape_display(const char* str)
{
- char *r, *w, *rc = malloc((2 * strlen(str) + 1) * sizeof(char));
+ char *r, *w, *rc = NULL;
int s = 0;
- if (!rc) return NULL;
- memcpy(rc, str, (strlen(str) + 1) * sizeof(char));
+ xmalloc(&rc, 2 * strlen(str) + 1);
+ strcpy(rc, str);
for (r = w = strchr(rc, '=') + 1; *r; r++) {
if (!s || (*r != '/')) {
if (strchr("@=/", *r)) *w++ = '@';
@@ -133,6 +127,7 @@ escape_display(const char* str)
}
}
w[s ? -2 : 0] = '\0';
+fail:
return rc;
}
@@ -149,9 +144,9 @@ get_display_string(const struct settings *settings)
const char *var, *val;
char *r, *d = NULL, *rc = NULL, **displays;
size_t i, n = 0, len = 0;
- int method, saved_errno;
+ int method;
- try (displays = malloc(settings->monitors_n * sizeof(char *)));
+ xmalloc(&displays, settings->monitors_n);
for (i = 0; i < settings->monitors_n; i++)
if ((settings->monitors_arg[i] == 'd') && strchr(settings->monitors_id[i], '='))
len += 1 + strlen(displays[n++] = settings->monitors_id[i]);
@@ -168,23 +163,23 @@ get_display_string(const struct settings *settings)
var = libgamma_method_default_site_variable(method);
val = libgamma_method_default_site(method);
if (!val) return strdup("");
- try (d = malloc((3 + strlen(var) + strlen(val)) * sizeof(char)));
+ xmalloc(&d, 3 + strlen(var) + strlen(val));
stpcpy(stpcpy(stpcpy(stpcpy(d, "."), var), "="), val);
- try (rc = escape_display(d));
+ try (rc = escape_display(d)); /* TODO strip screen number */
return free(d), rc;
custom:
qsort(displays, n, sizeof(*displays), displayenvcmp);
- try (r = rc = malloc((2 * len + 1) * sizeof(char)));
- for (i = 0; i < n; i++) {
- try (d = escape_display(displays[i]));
+ xmalloc(&rc, 2 * len + 1);
+ for (r = rc, i = 0; i < n; i++) {
+ try (d = escape_display(displays[i])); /* TODO see above */
r = stpcpy(stpcpy(r, "."), d), free(d), d = NULL;
}
free(displays);
return rc;
fail:
- saved_errno = errno, free(rc), free(d), free(displays), errno = saved_errno;
+ CLEANUP(free(rc), free(d), free(displays));
return NULL;
}
@@ -201,14 +196,15 @@ get_state_pathname(const struct settings *settings)
const char *dir = getenv("XGD_RUNTIME_DIR");
char *display = NULL;
char *env = NULL;
- int rc = -1, saved_errno;
+ int rc = -1;
try (display = get_display_string(settings));
if (!dir || !*dir) dir = "/run";
- try (env = malloc((strlen(dir) + sizeof("/radharc/") + strlen(display)) * sizeof(char)));
+ xmalloc(&env, strlen(dir) + sizeof("/radharc/") + strlen(display));
stpcpy(stpcpy(stpcpy(env, dir), "/radharc/"), display);
rc = setenv("RADHARC_STATE", env, 1);
fail:
- return saved_errno = errno, free(env), free(display), errno = saved_errno, rc;
+ CLEANUP(free(env), free(display));
+ return rc;
}
@@ -221,36 +217,37 @@ fail:
static int
get_clut_method(const char *display)
{
+#define HAIKU(TEXT) t ((msg = (TEXT)))
+
int method;
const char *env;
+ const char *msg;
if (!display) {
- if (!libgamma_list_methods(&method, 1, 0)) {
- fprintf(stderr, "No display was found.\n"
- "DRM support missing.\n"
- "Can you even see?\n");
- return errno = 0, -1;
- }
+ if (!libgamma_list_methods(&method, 1, 0))
+ HAIKU("No display was found.\n"
+ "DRM support missing.\n"
+ "Can you even see?\n");
return method;
}
if (!strcasecmp(display, "none")) return INT_MAX;
if (!strcasecmp(display, "drm")) return LIBGAMMA_METHOD_LINUX_DRM;
- if (!strchr(display, '=')) {
- fprintf(stderr, "Specified display\n"
- "cannot be recognised.\n"
- "Try something else.\n");
- return errno = 0, -1;
- }
+ if (!strchr(display, '='))
+ HAIKU("Specified display\n"
+ "cannot be recognised.\n"
+ "Try something else.\n");
for (method = 0; method < LIBGAMMA_METHOD_COUNT; method++) {
env = libgamma_method_default_site_variable(method);
if (env && (strstr(display, env) == display) && (display[strlen(env)] == '='))
return method;
}
+ HAIKU("Specified display\n"
+ "cannot be recognised.\n"
+ "Try to recompile.\n");
- fprintf(stderr, "Specified display\n"
- "cannot be recognised.\n"
- "Try to recompile.\n");
+fail:
+ fprintf(stderr, "%s", msg);
return errno = 0, -1;
}
@@ -266,15 +263,13 @@ initialise_clut(const struct settings *settings)
{
#define NONE_METHOD (method == INT_MAX)
- int method = 0, error = 0, is_none = 0;
+ int method = 0, error = 0;
const char *sitename_;
char *sitename = NULL;
- void *new;
size_t i, j, parts_off = 0;
libgamma_site_state_t site;
- int saved_errno;
- try (sites = calloc(settings->monitors_n + 1, sizeof(*sites)));
+ xcalloc(&sites, settings->monitors_n + 1);
for (i = 0; i < settings->monitors_n; i++) {
switch (settings->monitors_arg[i]) {
@@ -283,12 +278,11 @@ initialise_clut(const struct settings *settings)
t ((method = get_clut_method(sitename_ = settings->monitors_id[i])) < 0);
if (NONE_METHOD) break;
sitename_ = strchr(sitename_, '=');
- if (sitename_) try ((sitename = strdup(sitename_ + 1)));
+ xstrdup(&sitename, sitename_ ? sitename_ + 1 : NULL);
t ((error = libgamma_site_initialise(sites + sites_n, method, sitename)));
sitename = NULL;
site = sites[sites_n++];
- try (new = realloc(parts, (parts_n + site.partitions_available) * sizeof(*parts)));
- parts = new;
+ xrealloc(&parts, parts_n + site.partitions_available);
for (j = 0; j < site.partitions_available; j++) {
t ((error = libgamma_partition_initialise(parts + parts_n, &site, j)));
parts_n++;
@@ -307,13 +301,12 @@ initialise_clut(const struct settings *settings)
}
}
- new = realloc(sites, (sites_n + 1) * sizeof(*sites));
- sites = new ? new : sites;
+ SHRINK(&sites, sites_n + 1);
return 0;
fail:
if (error) libgamma_perror(argv0, error), errno = 0;
- saved_errno = errno, free(sitename), errno = saved_errno;
+ CLEANUP(free(sitename));
return -1;
}