diff options
-rw-r--r-- | src/blackbody.c | 9 | ||||
-rw-r--r-- | src/macros.h | 57 | ||||
-rw-r--r-- | src/parse_10deg.c | 12 | ||||
-rw-r--r-- | src/radharc.c | 5 | ||||
-rw-r--r-- | src/settings.c | 38 | ||||
-rw-r--r-- | src/state.c | 85 |
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; } |