+
+/*
+ * Converts a string into a long using strtol().
+ * This is a convenience wrapper checking the parsing result. It returns true
+ * if the number could be parsed.
+ */
+bool parse_long(const char *str, long *out, int base) {
+ char *end;
+ long result = strtol(str, &end, base);
+ if (result == LONG_MIN || result == LONG_MAX || result < 0 || (end != NULL && *end != '\0')) {
+ *out = result;
+ return false;
+ }
+
+ *out = result;
+ return true;
+}
+
+/*
+ * Slurp reads path in its entirety into buf, returning the length of the file
+ * or -1 if the file could not be read. buf is set to a buffer of appropriate
+ * size, or NULL if -1 is returned.
+ *
+ */
+ssize_t slurp(const char *path, char **buf) {
+ FILE *f;
+ if ((f = fopen(path, "r")) == NULL) {
+ ELOG("Cannot open file \"%s\": %s\n", path, strerror(errno));
+ return -1;
+ }
+ struct stat stbuf;
+ if (fstat(fileno(f), &stbuf) != 0) {
+ ELOG("Cannot fstat() \"%s\": %s\n", path, strerror(errno));
+ fclose(f);
+ return -1;
+ }
+ /* Allocate one extra NUL byte to make the buffer usable with C string
+ * functions. yajl doesn’t need this, but this makes slurp safer. */
+ *buf = scalloc(stbuf.st_size + 1, 1);
+ size_t n = fread(*buf, 1, stbuf.st_size, f);
+ fclose(f);
+ if ((ssize_t)n != stbuf.st_size) {
+ ELOG("File \"%s\" could not be read entirely: got %zd, want %" PRIi64 "\n", path, n, (int64_t)stbuf.st_size);
+ free(*buf);
+ *buf = NULL;
+ return -1;
+ }
+ return (ssize_t)n;
+}
+
+/*
+ * Convert a direction to its corresponding orientation.
+ *
+ */
+orientation_t orientation_from_direction(direction_t direction) {
+ return (direction == D_LEFT || direction == D_RIGHT) ? HORIZ : VERT;
+}