]> git.draconx.ca Git - liblbx.git/commitdiff
tools: Add some smarter error printing routines.
authorNick Bowler <nbowler@draconx.ca>
Wed, 5 Jun 2013 03:34:06 +0000 (23:34 -0400)
committerNick Bowler <nbowler@draconx.ca>
Fri, 14 Jun 2013 20:32:56 +0000 (16:32 -0400)
These ones can fill in strerror(errno) automatically.

src/lbximg.c
src/lbxtool.c
src/tools.c
src/tools.h

index 581a33ac0b3153353caaff20d183ff2cc623e3e3..ff38c89b71f998f0dff387f5f2404e4ffb0783cf 100644 (file)
@@ -64,12 +64,12 @@ int parserange(unsigned frames, char *str, unsigned char *bits)
 
        start = strtoul(str, &endptr, 0);
        if (start >= frames) {
-               errmsg("frame %lu out of range.\n", start);
+               tool_err(-1, "frame %lu out of range.", start);
                return -1;
        }
 
        if (endptr == str) {
-               errmsg("invalid frame range: %s.\n", str);
+               tool_err(-1, "invalid frame range: %s.", str);
                return -1;
        }
 
@@ -80,7 +80,7 @@ int parserange(unsigned frames, char *str, unsigned char *bits)
        case '-':
                end = strtoul(endptr+1, &endptr, 0);
                if (end >= frames) {
-                       errmsg("frame %lu out of range.\n", end);
+                       tool_err(-1, "frame %lu out of range.", end);
                        return -1;
                }
 
@@ -88,12 +88,12 @@ int parserange(unsigned frames, char *str, unsigned char *bits)
                        end = frames - 1;
                break;
        default:
-               errmsg("invalid frame range: %s.\n", str);
+               tool_err(-1, "invalid frame range: %s.", str);
                return -1;
        }
 
        if (end < start) {
-               errmsg("invalid frame range: %s.\n", str);
+               tool_err(-1, "invalid frame range: %s.", str);
                return -1;
        }
 
@@ -134,26 +134,25 @@ int outpng(unsigned int frameno,
 
        row = malloc(4 * width);
        if (!row) {
-               errmsg("failed to allocate row buffer: %s\n", strerror(errno));
+               tool_err(0, "failed to allocate row buffer");
                return -1;
        }
 
        of = fopen(name, "wb");
        if (!of) {
-               errmsg("failed to open %s: %s.\n", name, strerror(errno));
-               free(row);
+               tool_err(0, "failed to open %s", name);
                return -1;
        }
 
        png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
        if (!png) {
-               errmsg("failed to init libpng.\n", 0);
+               tool_err(-1, "failed to init libpng.");
                goto err;
        }
 
        info = png_create_info_struct(png);
        if (!info) {
-               errmsg("failed to init libpng.\n", 0);
+               tool_err(-1, "failed to init libpng.");
                png_destroy_write_struct(&png, NULL);
                goto err;
        }
@@ -234,19 +233,19 @@ static int loadoverride(FILE *f, struct lbx_colour palette[static 256])
        struct lbx_imginfo info;
 
        if (!overimg) {
-               errmsg("failed to open override image: %s\n", lbx_errmsg());
+               tool_err(-1, "failed to open override image: %s", lbx_errmsg());
                return -1;
        }
        lbx_img_getinfo(overimg, &info);
 
        if (!info.palettesz) {
-               errmsg("override image has no palette.\n", 0);
+               tool_err(-1, "override image has no palette.");
                lbx_img_close(overimg);
                return -1;
        }
 
        if (lbx_img_getpalette(overimg, palette) == -1) {
-               errmsg("error reading override palette: %s\n", lbx_errmsg());
+               tool_err(-1, "error reading override palette: %s", lbx_errmsg());
                lbx_img_close(overimg);
                return -1;
        }
@@ -272,7 +271,7 @@ static int loadpalette(struct lbx_image *img, struct lbx_imginfo *info,
 
        /* For sanity. */
        if (!palf && !info->palettesz && !override) {
-               errmsg("no palette available.\n", 0);
+               tool_err(-1, "no palette available.");
                return -1;
        }
 
@@ -283,13 +282,13 @@ static int loadpalette(struct lbx_image *img, struct lbx_imginfo *info,
 
        /* Read the external palette, if any. */
        if (palf && lbx_img_loadpalette(palf, &lbx_default_fops, palette) != 0) {
-               errmsg("error reading external palette: %s\n", lbx_errmsg());
+               tool_err(-1, "error reading external palette: %s", lbx_errmsg());
                return -1;
        }
 
        /* Read the embedded palette, if any. */
        if (info->palettesz && lbx_img_getpalette(img, palette) == -1) {
-               errmsg("error reading embedded palette: %s\n", lbx_errmsg());
+               tool_err(-1, "error reading embedded palette: %s", lbx_errmsg());
                return -1;
        }
 
@@ -340,7 +339,7 @@ int decode(struct lbx_image *img, FILE *palf, FILE *override, char **argv)
 
                data = lbx_img_getframe(img, i);
                if (!data) {
-                       errmsg("error in frame %u: %s\n", i, lbx_errmsg());
+                       tool_err(-1, "error in frame %u: %s", i, lbx_errmsg());
                        continue;
                }
 
@@ -352,7 +351,7 @@ int decode(struct lbx_image *img, FILE *palf, FILE *override, char **argv)
        }
 
        if (!extracted) {
-               errmsg("no frames extracted.\n", 0);
+               tool_err(-1, "no frames extracted.");
                goto err;
        }
 
@@ -410,7 +409,7 @@ int main(int argc, char **argv)
                case 'p':
                        palf = fopen(optarg, "rb");
                        if (!palf) {
-                               errmsg("failed to open %s: %m\n", optarg);
+                               tool_err(0, "failed to open %s", optarg);
                                return EXIT_FAILURE;
                        }
 
@@ -418,7 +417,7 @@ int main(int argc, char **argv)
                case 'O':
                        overf = fopen(optarg, "rb");
                        if (!overf) {
-                               errmsg("failed to open %s: %m\n", optarg);
+                               tool_err(0, "failed to open %s", optarg);
                                return EXIT_FAILURE;
                        }
                        break;
@@ -438,7 +437,7 @@ int main(int argc, char **argv)
        }
 
        if (mode == MODE_NONE) {
-               errmsg("you must specify a mode.\n", 0);
+               tool_err(-1, "you must specify a mode.");
                return EXIT_FAILURE;
        }
 
@@ -448,7 +447,7 @@ int main(int argc, char **argv)
                img = lbx_img_open(&stdin_handle, &lbx_pipe_fops, NULL);
 
        if (!img) {
-               errmsg("failed to open image: %s.\n", lbx_errmsg());
+               tool_err(-1, "failed to open image: %s.", lbx_errmsg());
                return EXIT_FAILURE;
        }
 
index 1c32ef47758b0d8df68d75d4e7aca4c0c2941913..767c30925b26c5d564920dbc154107a36a9066dd 100644 (file)
@@ -56,7 +56,7 @@ int filematch(char **argv, const char *name)
                case FNM_NOMATCH:
                        break;
                default:
-                       errmsg("error matching glob: %s.\n", argv[i]);
+                       tool_err(-1, "error matching glob: %s", argv[i]);
                        return 1;
                }
        }
@@ -102,8 +102,7 @@ int extract_file(LBXfile *f, const struct lbx_statbuf *stat)
 
        of = fopen(stat->name, "wb");
        if (!of) {
-               errmsg("%s: fopen: %s\n",
-                       stat->name, strerror(errno));
+               tool_err(0, "%s: fopen", stat->name);
                return -1;
        }
 
@@ -118,7 +117,7 @@ int extract_file(LBXfile *f, const struct lbx_statbuf *stat)
                }
 
                if (fwrite(buf, rc, 1, of) != 1) {
-                       errmsg("%s: fwrite: %s\n", stat->name, strerror(errno));
+                       tool_err(0, "%s: fwrite", stat->name);
                        break;
                }
 
@@ -130,7 +129,7 @@ int extract_file(LBXfile *f, const struct lbx_statbuf *stat)
        }
 
        if (fclose(of) == EOF) {
-               errmsg("%s: fclose: %s\n", stat->name, strerror(errno));
+               tool_err(0, "%s: fclose", stat->name);
                return -1;
        }
 
@@ -159,7 +158,7 @@ int extract(struct lbx *lbx, int verbose, char **argv)
 
                file = lbx_file_open(lbx, i);
                if (!file) {
-                       errmsg("%s: %s.\n", stat.name, lbx_errmsg());
+                       tool_err(-1, "%s: %s", stat.name, lbx_errmsg());
                        continue;
                }
 
@@ -233,7 +232,7 @@ int main(int argc, char **argv)
                lbx = lbx_open(&stdin_handle, &lbx_pipe_fops, NULL, "stdin");
 
        if (!lbx) {
-               errmsg("%s: %s.\n", file ? file : "stdin", lbx_errmsg());
+               tool_err(-1, "%s: %s", file ? file : "stdin", lbx_errmsg());
                return EXIT_FAILURE;
        }
 
@@ -245,7 +244,7 @@ int main(int argc, char **argv)
                rc = extract(lbx, verbose, &argv[optind]);
                break;
        default:
-               errmsg("you must specify a mode.\n", 0);
+               tool_err(-1, "no mode specified");
        }
 
        lbx_close(lbx);
index b80e5212966e234ffe54d495ea67d4a0b7c9caba..200cf9c289e023e20f10681576f4fbf8062e5aac 100644 (file)
 
 #include <config.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <limits.h>
+#include <inttypes.h>
 #include <assert.h>
 
 #include "tools.h"
@@ -46,3 +52,91 @@ const char *tool_invocation(void)
        assert(argv0 != NULL);
        return argv0;
 }
+
+/* Saturating addition. */
+static size_t add_size(size_t a, size_t b)
+{
+       if (a >= SIZE_MAX - b)
+               return SIZE_MAX;
+       return a + b;
+}
+
+static int vfmsg_internal(FILE *f, int err, const char *fmt, va_list ap)
+{
+       size_t invokelen, fmtlen, errlen, totlen;
+       char *newfmt, *errmsg;
+       int rc;
+
+       invokelen = strlen(tool_invocation());
+       fmtlen = fmt ? strlen(fmt) : 0;
+       errlen = err > 0 ? strlen(errmsg = strerror(err)) : 0;
+
+       totlen = add_size(invokelen, sizeof "\n");
+       if (fmtlen > 0) {
+               totlen = add_size(totlen, strlen(": "));
+               totlen = add_size(totlen, fmtlen);
+       }
+       if (errlen > 0) {
+               totlen = add_size(totlen, strlen(": "));
+               totlen = add_size(totlen, errlen);
+       }
+
+       if (totlen == SIZE_MAX || totlen > INT_MAX)
+               return -1;
+
+       newfmt = malloc(totlen);
+       if (!newfmt)
+               return -1;
+
+       if (errlen && fmtlen)
+               rc = sprintf(newfmt, "%s: %s: %s\n", argv0, fmt, errmsg);
+       else if (errlen)
+               rc = sprintf(newfmt, "%s: %s\n", argv0, errmsg);
+       else if (fmtlen)
+               rc = sprintf(newfmt, "%s: %s\n", argv0, fmt);
+       else
+               rc = sprintf(newfmt, "%s\n", argv0);
+
+       assert(rc < totlen);
+       if (rc < 0)
+               goto out;
+
+       rc = vfprintf(f, newfmt, ap);
+out:
+       free(newfmt);
+       return rc;
+}
+
+int tool_vmsg(const char *fmt, va_list ap)
+{
+       return vfmsg_internal(stdout, -1, fmt, ap);
+}
+
+int tool_verr(int err, const char *fmt, va_list ap)
+{
+       return vfmsg_internal(stderr, err == 0 ? errno : err, fmt, ap);
+}
+
+int tool_msg(const char *fmt, ...)
+{
+       va_list ap;
+       int rc;
+
+       va_start(ap, fmt);
+       rc = tool_vmsg(fmt, ap);
+       va_end(ap);
+
+       return rc;
+}
+
+int tool_err(int err, const char *fmt, ...)
+{
+       va_list ap;
+       int rc;
+
+       va_start(ap, fmt);
+       rc = tool_verr(err, fmt, ap);
+       va_end(ap);
+
+       return rc;
+}
index 315d9654fbe5ddbcc368833a834284f18e769dee..c2c10fff40d77f59666a4023682e2a621f7d6d18 100644 (file)
 #ifndef TOOLS_H_
 #define TOOLS_H_
 
+#include <stdarg.h>
+
 void tool_init(const char *name, int argc, char **argv);
 void tool_version(void);
 
 const char *tool_invocation(void);
 
-#define errmsg(fmt, ...) (\
-       fprintf(stderr, "%s: " fmt, tool_invocation(), __VA_ARGS__)\
-)
+/*
+ * Error messaging routines.  Similar to printf, but writes to standard error
+ * and prefixes the output with the program invocation name, automatically
+ * appending a newline.  If err is 0, the result of strerror(errno) is also
+ * printed in a similar manner as perror.  If err is positive, then that
+ * value is used instead of errno.
+ */
+int tool_verr(int err, const char *fmt, va_list ap);
+int tool_err(int err, const char *fmt, ...);
+
+/*
+ * Messaging routines similar to the above, except that they write to standard
+ * output and there is no option to include strerror(errno).
+ */
+int tool_vmsg(const char *fmt, va_list ap);
+int tool_msg(const char *fmt, ...);
 
 #endif