From 5620b7ffb09ddfc56cb20e7de5262729272299eb Mon Sep 17 00:00:00 2001 From: Trent Huber Date: Mon, 5 May 2025 22:29:07 -0400 Subject: [PATCH] Use err.h for error messaging --- build.h | 28 +++++---------- clean.c | 12 +++---- external/build.c | 36 ++++++++++++++----- external/cbs | 2 +- src/build.c | 20 +++++++---- src/cbs.h | 3 ++ src/colors.h | 7 ++++ src/colors/build.c | 11 +++--- src/colors/gencolors.c | 60 ++++++++++++++++---------------- src/font/build.c | 15 +++++--- src/font/genfont.c | 15 ++++---- src/main.c | 10 ++---- src/options.c | 17 ++++----- src/utilities.c | 29 ---------------- src/utilities.h | 2 -- src/xpm.c | 79 +++++++++++++++++++++++++----------------- 16 files changed, 176 insertions(+), 170 deletions(-) create mode 100644 src/cbs.h create mode 100644 src/colors.h delete mode 100644 src/utilities.c delete mode 100644 src/utilities.h diff --git a/build.h b/build.h index 1a61d10..c184064 100644 --- a/build.h +++ b/build.h @@ -1,42 +1,32 @@ /* Switch the following #define to change whether or not raylib is built as a * static or dynamic library; be sure to `clean' before you `build' again. */ -// #define RLDYNAMIC +// #define DYNAMICLIBS -#ifdef RLDYNAMIC -#define RLEXT DYEXT +#ifdef DYNAMICLIBS +#define LIBEXT DYEXT #else -#define RLEXT ".a" +#define LIBEXT ".a" #endif -#define CBSPATH ROOT "external/cbs/" -#define CBS CBSPATH "cbs.c" +#define CBSROOT ROOT "external/cbs/" +#define CBSLIB CBSROOT "cbs" LIBEXT #define RLROOT ROOT "external/raylib/" -#define RLLIB RLROOT "raylib" RLEXT +#define RLLIB RLROOT "raylib" LIBEXT #define RLSRC RLROOT "src/" #define RLHDR RLSRC "raylib" #define SIMPLEXPM ROOT "bin/simplexpm" #define SRC ROOT "src/" -#define UTILS SRC "utilities" -#define CFCBS "-I" CBSPATH #define CFRAYLIB "-I" RLSRC -#define CFSRC "-I" SRC #ifdef __APPLE__ -#define RLLFLAGS \ +#define LFRAYLIB \ "-framework", "Cocoa", \ "-framework", "CoreVideo", \ "-framework", "GLUT", \ "-framework", "IOKit", \ "-framework", "OpenGL" #else -#define RLLFLAGS "-lm" -#endif -#ifdef RLDYNAMIC -#define LFEXTERNAL RLLFLAGS -#define LFRAYLIB NULL -#else -#define LFEXTERNAL NULL -#define LFRAYLIB RLLFLAGS +#define LFRAYLIB "-lm" #endif diff --git a/clean.c b/clean.c index 1cce666..04a9da4 100644 --- a/clean.c +++ b/clean.c @@ -15,7 +15,7 @@ int main(void) { size_t i; pid_t cpid; - what = "removal"; + what = "remove"; // Remove build executables and object files whos = (char *[2]){"{*/*build,*/*/*build}", "{*/*.o,*/*/*.o,*/*/*/*.o}"}; @@ -27,16 +27,16 @@ int main(void) { await(cpid, what, whos[i]); } - /* Remove raylib library, application executables, + /* Remove cbs and raylib libraries, application executables, * automatically generated source files, and ourself */ - whos = (char *[4]){extend(RLLIB, RLEXT), + whos = (char *[5]){extend(CBSLIB, LIBEXT), extend(RLLIB, LIBEXT), "{" GENCOLORS "," GENFONT "," SIMPLEXPM "}", "{" COLORS "," FONT "}", "clean"}; - rms = (char **[4]){(char *[3]){whos[0]}, + rms = (char **[5]){(char *[3]){whos[0]}, (char *[3]){whos[1]}, (char *[3]){GENCOLORS, GENFONT, SIMPLEXPM}, - (char *[3]){COLORS, FONT}, (char *[3]){whos[3]}}; - for (i = 0; i < 4; ++i) { + (char *[3]){COLORS, FONT}, (char *[3]){whos[4]}}; + for (i = 0; i < 5; ++i) { if ((cpid = fork()) == 0) run(RM, (char *[]){"rm", "-f", rms[i][0], rms[i][1], rms[i][2], NULL}, what, whos[i]); diff --git a/external/build.c b/external/build.c index f8e5d9e..a3f4352 100644 --- a/external/build.c +++ b/external/build.c @@ -1,6 +1,9 @@ #define ROOT "../" #include "../build.h" +#include "cbs/cbs.c" + +#define CBSSRC CBSROOT "cbs" #define RLSRCS \ RLSRC "raudio", RLSRC "rmodels", \ RLSRC "rshapes", RLSRC "rtext", \ @@ -13,26 +16,34 @@ #define CFGRAPHICS "-D_GLFW_X11" #endif #define CFGLFW "-I" RLSRC "external/glfw/include" -#ifdef RLDYNAMIC -#define CFGLOBALS "-DPLATFORM_DESKTOP", "-fPIC" +#ifdef DYNAMICLIBS +#define CFPIC "-fPIC" #else -#define CFGLOBALS "-DPLATFORM_DESKTOP" +#define CFPIC NULL +#endif +#define CFGLOBALS "-DPLATFORM_DESKTOP", CFPIC + +#ifndef DYNAMICLIBS +#undef LFRAYLIB +#define LFRAYLIB NULL #endif -#ifdef RLDYNAMIC +#ifdef DYNAMICLIBS #define LIBTYPE 'd' #else #define LIBTYPE 's' #endif -#include "cbs/cbs.c" +void cbs(void) { + cflags = (char *[]){CFPIC, NULL}; + compile(CBSSRC, NULL); + load(LIBTYPE, CBSLIB, CBSSRC, NULL); +} -int main(void) { +void raylib(void) { char **src; size_t i; - build(NULL); - src = (char *[]){RLSRCS, NULL}; cflags = (char *[]){CFGLOBALS, NULL}; for (i = 0; i < 6; ++i) compile(src[i], NULL); @@ -41,8 +52,15 @@ int main(void) { cflags = (char *[]){CFGRAPHICS, CFGLFW, CFGLOBALS, NULL}; compile(src[7], NULL); - lflags = (char *[]){LFEXTERNAL, NULL}; + lflags = (char *[]){LFRAYLIB, NULL}; load(LIBTYPE, RLLIB, RLSRCS, NULL); +} + +int main(void) { + build(NULL); + + cbs(); + raylib(); return EXIT_SUCCESS; } diff --git a/external/cbs b/external/cbs index 47c262d..51d2489 160000 --- a/external/cbs +++ b/external/cbs @@ -1 +1 @@ -Subproject commit 47c262dc02e5f6ed3dba9e092a5f750084bfad95 +Subproject commit 51d2489cfcf1c245db14c3a9e7c9e40e6a550f4c diff --git a/src/build.c b/src/build.c index d828156..1734173 100644 --- a/src/build.c +++ b/src/build.c @@ -3,23 +3,29 @@ #include "../external/cbs/cbs.c" +#define CFDYEXT "-DDYEXT=\"" DYEXT "\"" + +#ifdef DYNAMICLIBS +#undef LFRAYLIB +#define LFRAYLIB NULL +#endif + int main(void) { build(NULL); - compile("utilities", NULL); - build("colors/"); build("font/"); + compile("colors", "colors", NULL); cflags = (char *[]){CFRAYLIB, NULL}; - compile("main", "utilities", "options", RLHDR, "xpm", "font.c", NULL); + compile("main", "cbs", "options", RLHDR, "xpm", "font.c", NULL); cflags = NULL; - compile("options", "utilities", NULL); - cflags = (char *[]){CFRAYLIB, CFCBS, NULL}; - compile("xpm", "utilities", RLHDR, "xpm", CBS, "colors.c", NULL); + compile("options", "cbs", NULL); + cflags = (char *[]){CFDYEXT, CFRAYLIB, NULL}; + compile("xpm", "cbs", "colors", RLHDR, "xpm", "colors.c", NULL); lflags = (char *[]){LFRAYLIB, NULL}; - load('x', SIMPLEXPM, "utilities", "main", "options", "xpm", RLLIB, NULL); + load('x', SIMPLEXPM, "colors", "main", "options", "xpm", CBSLIB, RLLIB, NULL); return EXIT_SUCCESS; } diff --git a/src/cbs.h b/src/cbs.h new file mode 100644 index 0000000..c81e516 --- /dev/null +++ b/src/cbs.h @@ -0,0 +1,3 @@ +void *allocate(size_t s); +void compile(char *src, ...); +void load(char type, char *target, char *obj, ...); diff --git a/src/colors.h b/src/colors.h new file mode 100644 index 0000000..9acbf69 --- /dev/null +++ b/src/colors.h @@ -0,0 +1,7 @@ +struct color { + char *name; + unsigned int value; +}; + +extern struct color colors[]; +extern size_t numcolors; diff --git a/src/colors/build.c b/src/colors/build.c index 7e83836..98326c3 100644 --- a/src/colors/build.c +++ b/src/colors/build.c @@ -1,20 +1,19 @@ #define ROOT "../../" #include "../../build.h" -#define COLORS SRC "colors.c" - #include "../../external/cbs/cbs.c" +#define COLORS SRC "colors.c" + int main(void) { build(NULL); - cflags = (char *[]){CFSRC, NULL}; - compile("gencolors", UTILS, NULL); - load('x', "gencolors", "gencolors", UTILS, NULL); + compile("gencolors", NULL); + load('x', "gencolors", "gencolors", NULL); if (modified(COLORS, "gencolors.c") || modified(COLORS, "rgb.txt")) run("gencolors", (char *[]){"./gencolors", "rgb.txt", COLORS, NULL}, - "execution", "gencolors"); + "run", "gencolors"); return EXIT_SUCCESS; } diff --git a/src/colors/gencolors.c b/src/colors/gencolors.c index b5dd82c..e5c4856 100644 --- a/src/colors/gencolors.c +++ b/src/colors/gencolors.c @@ -1,14 +1,12 @@ +#include #include #include #include #include -#include #include #include #include -#include "utilities.h" - int main(int argc, char **argv) { int result, infd, outfd; struct stat instat; @@ -18,37 +16,31 @@ int main(int argc, char **argv) { unsigned char r, g, b; result = EXIT_FAILURE; - if (argc != 3) { - xpmerror("Incorrect number of arguments: %s ", argv[0]); - return result; - } - if ((infd = open(argv[1], O_RDONLY)) == -1) { - xpmerror("Unable to open `%s' for reading", argv[1]); - return result; - } + if (argc != 3) + errx(EXIT_FAILURE, "Incorrect number of arguments: %s ", + argv[0]); + if ((infd = open(argv[1], O_RDONLY)) == -1) + err(EXIT_FAILURE, "Unable to open `%s' for reading", argv[1]); if (fstat(infd, &instat) == -1) { - xpmerror("Unable to stat `%s'", argv[1]); + warn("Unable to stat `%s'", argv[1]); goto closein; } l = instat.st_size; if ((p = map = mmap(NULL, l, PROT_READ | PROT_WRITE, MAP_PRIVATE, infd, 0)) == MAP_FAILED) { - xpmerror("Unable to map `%s' to memory", argv[1]); + warn("Unable to map `%s' to memory", argv[1]); goto closein; } if ((outfd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) { - xpmerror("Unable to open `%s' for writing", argv[2]); + warn("Unable to open `%s' for writing", argv[2]); goto munmap; } - result = EXIT_SUCCESS; - if (dprintf(outfd, "struct color {\n" - "\tchar *name;\n" - "\tunsigned int value;\n" - "};\n\n" - "static struct color colors[] = {\n" + if (dprintf(outfd, "#include \n\n" + "#include \"colors.h\"\n\n" + "struct color colors[] = {\n" "\t{\"None\", 0x00ffffff},\n") == -1) { - xpmerror("Unable to write to `%s'", argv[2]); + warn("Unable to write to `%s'", argv[2]); goto closeout; } for (i = 1; p < (char *)map + l; ++i) { @@ -57,24 +49,32 @@ int main(int argc, char **argv) { b = strtol(p, &p, 10); if (dprintf(outfd, "\t{\"%s\", 0x%02x%02x%02x},\n", strsep(&p, "\n") + 2, r, g, b) == -1) { - xpmerror("Unable to write to `%s'", argv[2]); + warn("Unable to write to `%s'", argv[2]); goto closeout; } } - if (dprintf(outfd, "};\n\nstatic size_t numcolors = %zu;\n", i) == -1) - xpmerror("Unable to write to `%s'", argv[2]); + if (dprintf(outfd, "};\n\nsize_t numcolors = %zu;\n", i) == -1) + warn("Unable to write to `%s'", argv[2]); + + result = EXIT_SUCCESS; closeout: - if (close(outfd) == -1) - xpmerror("Unable to close `%s'", argv[2]); + if (close(outfd) == -1) { + warn("Unable to close `%s'", argv[2]); + result = EXIT_FAILURE; + } munmap: - if (munmap(map, l) == -1) - xpmerror("Unable to unmap memory associated with `%s'", argv[1]); + if (munmap(map, l) == -1) { + warn("Unable to unmap memory associated with `%s'", argv[1]); + result = EXIT_FAILURE; + } closein: - if (close(infd) == -1) - xpmerror("Unable to close `%s'", argv[1]); + if (close(infd) == -1) { + warn("Unable to close `%s'", argv[1]); + result = EXIT_FAILURE; + } return result; } diff --git a/src/font/build.c b/src/font/build.c index 989db8b..b596a60 100644 --- a/src/font/build.c +++ b/src/font/build.c @@ -1,22 +1,27 @@ #define ROOT "../../" #include "../../build.h" +#include "../../external/cbs/cbs.c" + #define FONT SRC "font.c" -#include "../../external/cbs/cbs.c" +#ifdef DYNAMICLIBS +#undef LFRAYLIB +#define LFRAYLIB NULL +#endif int main(void) { build(NULL); - cflags = (char *[]){CFRAYLIB, CFSRC, NULL}; - compile("genfont", UTILS, RLHDR, NULL); + cflags = (char *[]){CFRAYLIB, NULL}; + compile("genfont", RLHDR, NULL); lflags = (char *[]){LFRAYLIB, NULL}; - load('x', "genfont", "genfont", UTILS, RLLIB, NULL); + load('x', "genfont", "genfont", RLLIB, NULL); if (modified(FONT, "genfont.c") || modified(FONT, "font.ttf")) run("genfont", (char *[]){"./genfont", "font.ttf", FONT, NULL}, - "execution", "genfont"); + "run", "genfont"); return EXIT_SUCCESS; } diff --git a/src/font/genfont.c b/src/font/genfont.c index 764916e..958e271 100644 --- a/src/font/genfont.c +++ b/src/font/genfont.c @@ -1,24 +1,21 @@ +#include #include #include "raylib.h" -#include "utilities.h" int main(int argc, char **argv) { Font font; - if (argc != 3) { - xpmerror("Incorrect number of arguments: %s ", argv[0]); - return EXIT_FAILURE; - } + if (argc != 3) + errx(EXIT_FAILURE, "Incorrect number of arguments: %s ", + argv[0]); SetTraceLogLevel(LOG_WARNING); InitWindow(0, 0, ""); font = LoadFontEx(argv[1], 48, NULL, 95); - if (!ExportFontAsCode(font, argv[2])) { - xpmerror("Unable to generate `%s' from `%s'", argv[2], argv[1]); - return EXIT_FAILURE; - } + if (!ExportFontAsCode(font, argv[2])) + errx(EXIT_FAILURE, "Unable to generate `%s' from `%s'", argv[2], argv[1]); UnloadFont(font); diff --git a/src/main.c b/src/main.c index b036508..265fc30 100644 --- a/src/main.c +++ b/src/main.c @@ -1,19 +1,13 @@ -#include #include #include #include -#include -#include -#include +#include "cbs.h" #include "options.h" #define SUPPORT_IMAGE_EXPORT #include "raylib.h" -#include "utilities.h" #include "xpm.h" -extern bool isGpuReady; - #include "font.c" static void getinput(char **xp, Texture2D *tp, Image *ip) { @@ -25,7 +19,7 @@ static void getinput(char **xp, Texture2D *tp, Image *ip) { if (IsFileDropped()) { files = LoadDroppedFiles(); if (*xp) RL_FREE(*xp); - *xp = xpmalloc(FILENAME_MAX); + *xp = allocate(FILENAME_MAX); strcpy(*xp, files.paths[0]); UnloadDroppedFiles(files); *tp = gettexture(*xp, ip, mode); diff --git a/src/options.c b/src/options.c index 62966dc..e985db6 100644 --- a/src/options.c +++ b/src/options.c @@ -1,10 +1,11 @@ +#include #include #include #include #include #include -#include "utilities.h" +#include "cbs.h" static void usage(char *prog, int fd) { dprintf(fd, "Usage: %s [-dh] [-f file]\n" @@ -31,7 +32,7 @@ int options(int argc, char **argv, int *debug, char **xp) { *debug = 1; break; case 'f': - *xp = xpmalloc(FILENAME_MAX); + *xp = allocate(FILENAME_MAX); strcpy(*xp, optarg); break; case 'h': @@ -46,18 +47,18 @@ int options(int argc, char **argv, int *debug, char **xp) { result = 1; if (!*debug) { if ((dnfd = open("/dev/null", O_WRONLY)) == -1) { - xpmerror("Unable to open `/dev/null'; showing debug messages"); - return 0; + warn("Unable to open `/dev/null'; showing debug messages"); + return result; } if (close(STDOUT_FILENO) == -1) { - xpmerror("Unable to close stdout"); + warn("Unable to close stdout"); result = 0; } else if (dup2(dnfd, STDOUT_FILENO) == -1) { - xpmerror("Unable to redirect stdout to `/dev/null'"); - exit(EXIT_FAILURE); + warn("Unable to redirect stdout to `/dev/null'"); + result = 0; } if (close(dnfd) == -1) { - xpmerror("Unable to close `/dev/null'"); + warn("Unable to close `/dev/null'"); result = 0; } } diff --git a/src/utilities.c b/src/utilities.c deleted file mode 100644 index 00d780f..0000000 --- a/src/utilities.c +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include -#include -#include -#include -#include - -void xpmerror(char *fmt, ...) { - va_list args; - - dprintf(STDERR_FILENO, "simplexpm: "); - va_start(args, fmt); - vdprintf(STDERR_FILENO, fmt, args); - va_end(args); - if (errno) { - dprintf(STDERR_FILENO, ": %s", strerror(errno)); - errno = 0; - } - dprintf(STDERR_FILENO, "\n"); -} - -void *xpmalloc(size_t s) { - void *r; - - if ((r = malloc(s))) return memset(r, 0, s); - - xpmerror("Memory allocation"); - exit(EXIT_FAILURE); -} diff --git a/src/utilities.h b/src/utilities.h deleted file mode 100644 index d73b62c..0000000 --- a/src/utilities.h +++ /dev/null @@ -1,2 +0,0 @@ -void xpmerror(char *fmt, ...); -void *xpmalloc(size_t s); diff --git a/src/xpm.c b/src/xpm.c index 9b83f63..fa048b2 100644 --- a/src/xpm.c +++ b/src/xpm.c @@ -1,18 +1,22 @@ #include +#include #include +#include +#include +#include #include +#include +#include +#include "cbs.h" +#include "colors.h" #include "raylib.h" -#include "utilities.h" #include "xpm.h" #define TMP "/tmp/xpm" #define TMPSRC TMP ".c" #define TMPLIB "/tmp/libxpm" DYEXT -#include "cbs.c" -#include "colors.c" - static char *strnsub(char *str, char *sub, size_t l) { size_t subl; @@ -40,7 +44,7 @@ static char *arrname(char *p, size_t l) { start = p; for (; !space(*p) && *p != '['; ++p, --l) if (l == 0) return NULL; l = p - start; - r = xpmalloc(l + 1); + r = allocate(l + 1); strncpy(r, start, l); return r; @@ -76,7 +80,7 @@ static int key2mode(char **strp) { r = MODEC; break; default: - xpmerror("Unknown key `%c'", *(*strp - 1)); + warnx("Unknown key `%c'", *(*strp - 1)); r = NUMMODES; break; case 's': @@ -116,12 +120,12 @@ static unsigned int str2color(char **strp) { } } if (i == numcolors) { - xpmerror("`%s' is not a valid color name", *strp); + warnx("`%s' is not a valid color name", *strp); return 0; } if (r > 0xffffff) { - xpmerror("`0x%06x' is not a valid RGB color", r); + warnx("`0x%06x' is not a valid RGB color", r); return 0; } if (lendian()) r = (r >> 16 & 0xff) | (r & 0xff00) | (r & 0xff) << 16; @@ -148,13 +152,13 @@ static Image parse(char **data, long *sizep) { ncolors = strtol(p, &p, 10); cpp = strtol(p, &p, 10); if (1 + ncolors + height > *sizep) { - xpmerror("Actual image height too short"); + warnx("Actual image height too short"); return result; } // Colors - chars = xpmalloc(ncolors * cpp * sizeof*chars); - colors = xpmalloc(NUMMODES * ncolors * sizeof*colors); + chars = allocate(ncolors * cpp * sizeof*chars); + colors = allocate(NUMMODES * ncolors * sizeof*colors); for (i = 0; i < ncolors; ++i) { p = data[1 + i]; strncpy(chars + i * cpp, p, cpp); @@ -174,7 +178,7 @@ static Image parse(char **data, long *sizep) { } // Pixels - pixels = xpmalloc(NUMMODES * height * width * sizeof*pixels); + pixels = allocate(NUMMODES * height * width * sizeof*pixels); j = width; l = 0; for (i = 0, pp = &data[1 + ncolors]; @@ -188,7 +192,7 @@ static Image parse(char **data, long *sizep) { for (m = 0; m < NUMMODES; ++m) pixels[m * width * height + i * width + j] = colors[m * ncolors + k]; if (j != width || l != 0) { - xpmerror("Actual image width too narrow"); + warnx("Actual image width too narrow"); goto free; } @@ -216,44 +220,43 @@ static Image process(char *xpm) { void *d; long *sizep; - errno = 0; result = (Image){0}; if ((xpmfd = open(xpm, O_RDONLY)) == -1) { - xpmerror("Unable to open `%s'", xpm); + warn("Unable to open `%s'", xpm); return result; } if (stat(xpm, &xstat) == -1) { - xpmerror("Unable to stat `%s'", xpm); + warn("Unable to stat `%s'", xpm); goto close; } l = xstat.st_size; if ((map = mmap(NULL, l, PROT_READ, MAP_PRIVATE, xpmfd, 0)) == MAP_FAILED) { - xpmerror("Unable to map `%s' to memory", xpm); + warn("Unable to map `%s' to memory", xpm); goto close; } if ((p = strnsub(map, "char", l)) == NULL) { // Skip "static" keyword - xpmerror("`%s' improperly formatted", xpm); + warnx("`%s' improperly formatted", xpm); goto munmap; } offset = p - map; if ((a = arrname(p + 4, l - offset - 4)) == NULL) { - xpmerror("`%s' improperly formatted", xpm); + warnx("`%s' improperly formatted", xpm); goto munmap; } if ((srcfd = open(TMPSRC, O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) { - xpmerror("Unable to open `" TMPSRC "'"); + warn("Unable to open `" TMPSRC "'"); goto munmap; } e = !writeall(srcfd, p, l - offset) || dprintf(srcfd, "\n\nlong size = sizeof %s / sizeof*%s;\n", a, a) < 0; if (close(srcfd) == -1) { - xpmerror("Unable to close `" TMPSRC "'"); + warn("Unable to close `" TMPSRC "'"); goto munmap; } if (e) { - xpmerror("Unable to write to `" TMPSRC "'"); + warn("Unable to write to `" TMPSRC "'"); goto munmap; } @@ -262,35 +265,49 @@ static Image process(char *xpm) { load('d', TMP, TMP, NULL); exit(EXIT_SUCCESS); } - if (cpid == -1 || waitpid(cpid, &status, 0) == -1 - || !WIFEXITED(status) || WEXITSTATUS(status) != EXIT_SUCCESS) { - xpmerror("Unable to create `" TMPLIB "'"); + if (cpid == -1 || waitpid(cpid, &status, 0) == -1) { + warn("Unable to create `" TMPLIB "'"); goto munmap; } + if (!WIFEXITED(status) || WEXITSTATUS(status) != EXIT_SUCCESS) goto munmap; if ((d = dlopen(TMPLIB, RTLD_LAZY)) == NULL) { - xpmerror("Unable to load `" TMPLIB "': %s", dlerror()); + warnx("Unable to load `" TMPLIB "': %s", dlerror()); goto munmap; } if ((data = (char **)dlsym(d, a)) == NULL) { - xpmerror("Unable to load image data from `" TMPLIB "': `%s'", dlerror()); + warnx("Unable to load image data from `" TMPLIB "': `%s'", dlerror()); goto dlclose; } if ((sizep = (long *)dlsym(d, "size")) == NULL) { - xpmerror("Unable to load image length from `" TMPLIB "': `%s'", dlerror()); + warnx("Unable to load image size from `" TMPLIB "': `%s'", dlerror()); goto dlclose; } result = parse(data, sizep); dlclose: - if (dlclose(d)) xpmerror("Unable to unload `" TMPLIB "': %s", dlerror()); + if (dlclose(d)) { + warnx("Unable to unload `" TMPLIB "': %s", dlerror()); + result.mipmaps = 0; + } munmap: - if (munmap(map, l) == -1) xpmerror("Unable to unmap `%s' from memory", xpm); + if (munmap(map, l) == -1) { + warn("Unable to unmap `%s' from memory", xpm); + result.mipmaps = 0; + } close: - if (close(xpmfd) == -1) xpmerror("Unable to close `%s'", xpm); + if (close(xpmfd) == -1) { + warn("Unable to close `%s'", xpm); + result.mipmaps = 0; + } + + if (result.data && !result.mipmaps) { + free(result.data); + result = (Image){0}; + } return result; } -- 2.51.0