improve error handling

- errors are now fatal
- no need to clean up when dying
- no need for status return codes => ffread and ffprepare now return void
This commit is contained in:
Markus Teich 2016-02-06 14:08:43 +01:00
parent 77809fae79
commit 3019229279

112
sent.c
View File

@ -89,14 +89,13 @@ typedef struct {
static Image *ffopen(char *filename); static Image *ffopen(char *filename);
static void fffree(Image *img); static void fffree(Image *img);
static int ffread(Image *img); static void ffread(Image *img);
static int ffprepare(Image *img); static void ffprepare(Image *img);
static void ffscale(Image *img); static void ffscale(Image *img);
static void ffdraw(Image *img); static void ffdraw(Image *img);
static void getfontsize(Slide *s, unsigned int *width, unsigned int *height); static void getfontsize(Slide *s, unsigned int *width, unsigned int *height);
static void cleanup(); static void cleanup();
static void eprintf(const char *, ...);
static void die(const char *, ...); static void die(const char *, ...);
static void load(FILE *fp); static void load(FILE *fp);
static void advance(const Arg *arg); static void advance(const Arg *arg);
@ -142,11 +141,11 @@ filter(int fd, const char *cmd)
int fds[2]; int fds[2];
if (pipe(fds) < 0) if (pipe(fds) < 0)
eprintf("pipe:"); die("Unable to create pipe:");
switch (fork()) { switch (fork()) {
case -1: case -1:
eprintf("fork:"); die("Unable to fork:");
case 0: case 0:
dup2(fd, 0); dup2(fd, 0);
dup2(fds[1], 1); dup2(fds[1], 1);
@ -183,14 +182,13 @@ ffopen(char *filename)
return NULL; return NULL;
if ((fd = open(filename, O_RDONLY)) < 0) { if ((fd = open(filename, O_RDONLY)) < 0) {
eprintf("Unable to open file %s:", filename); die("Unable to open file %s:", filename);
return NULL;
} }
tmpfd = fd; tmpfd = fd;
fd = filter(fd, bin); fd = filter(fd, bin);
if (fd < 0) if (fd < 0)
eprintf("Unable to filter %s:", filename); die("Unable to filter %s:", filename);
close(tmpfd); close(tmpfd);
if (read(fd, hdr, 16) != 16) if (read(fd, hdr, 16) != 16)
@ -216,7 +214,7 @@ fffree(Image *img)
free(img); free(img);
} }
int void
ffread(Image *img) ffread(Image *img)
{ {
uint32_t y, x; uint32_t y, x;
@ -226,25 +224,20 @@ ffread(Image *img)
size_t rowlen, off, nbytes; size_t rowlen, off, nbytes;
ssize_t count; ssize_t count;
if (!img)
return 0;
if (img->state & LOADED) if (img->state & LOADED)
return 2; return;
if (img->buf) if (img->buf)
free(img->buf); free(img->buf);
/* internally the image is stored in 888 format */ /* internally the image is stored in 888 format */
if (!(img->buf = malloc(3 * img->bufwidth * img->bufheight))) if (!(img->buf = malloc(3 * img->bufwidth * img->bufheight)))
return 0; die("Unable to malloc buffer for image.");
/* scratch buffer to read row by row */ /* scratch buffer to read row by row */
rowlen = img->bufwidth * 2 * strlen("RGBA"); rowlen = img->bufwidth * 2 * strlen("RGBA");
row = malloc(rowlen); row = malloc(rowlen);
if (!row) { if (!row) {
free(img->buf); die("Unable to malloc buffer for image row.");
img->buf = NULL;
return 0;
} }
/* extract window background color channels for transparency */ /* extract window background color channels for transparency */
@ -257,7 +250,7 @@ ffread(Image *img)
while (nbytes < rowlen) { while (nbytes < rowlen) {
count = read(img->fd, (char *)row + nbytes, rowlen - nbytes); count = read(img->fd, (char *)row + nbytes, rowlen - nbytes);
if (count < 0) if (count < 0)
eprintf("Unable to read from pipe:"); die("Unable to read from pipe:");
nbytes += count; nbytes += count;
} }
for (x = 0; x < rowlen / 2; x += 4) { for (x = 0; x < rowlen / 2; x += 4) {
@ -276,11 +269,9 @@ ffread(Image *img)
free(row); free(row);
close(img->fd); close(img->fd);
img->state |= LOADED; img->state |= LOADED;
return 1;
} }
int void
ffprepare(Image *img) ffprepare(Image *img)
{ {
int depth = DefaultDepth(xw.dpy, xw.scr); int depth = DefaultDepth(xw.dpy, xw.scr);
@ -292,35 +283,21 @@ ffprepare(Image *img)
else else
height = img->bufheight * xw.uw / img->bufwidth; height = img->bufheight * xw.uw / img->bufwidth;
if (depth < 24) { if (depth < 24)
eprintf("Display depths <24 not supported."); die("Display depths <24 not supported.");
return 0;
}
if (!(img->ximg = XCreateImage(xw.dpy, CopyFromParent, depth, ZPixmap, 0, if (!(img->ximg = XCreateImage(xw.dpy, CopyFromParent, depth, ZPixmap, 0,
NULL, width, height, 32, 0))) { NULL, width, height, 32, 0)))
eprintf("Unable to create XImage."); die("Unable to create XImage.");
return 0;
}
if (!(img->ximg->data = malloc(img->ximg->bytes_per_line * height))) { if (!(img->ximg->data = malloc(img->ximg->bytes_per_line * height)))
eprintf("Unable to alloc data section for XImage."); die("Unable to alloc data section for XImage.");
XDestroyImage(img->ximg);
img->ximg = NULL;
return 0;
}
if (!XInitImage(img->ximg)) { if (!XInitImage(img->ximg))
eprintf("Unable to init XImage."); die("Unable to init XImage.");
free(img->ximg->data);
XDestroyImage(img->ximg);
img->ximg = NULL;
return 0;
}
ffscale(img); ffscale(img);
img->state |= SCALED; img->state |= SCALED;
return 1;
} }
void void
@ -421,18 +398,6 @@ die(const char *fmt, ...)
{ {
va_list ap; va_list ap;
va_start(ap, fmt);
eprintf(fmt, ap);
va_end(ap);
exit(1);
}
void
eprintf(const char *fmt, ...)
{
va_list ap;
fputs("sent: ", stderr); fputs("sent: ", stderr);
va_start(ap, fmt); va_start(ap, fmt);
@ -445,6 +410,8 @@ eprintf(const char *fmt, ...)
} else { } else {
fputc('\n', stderr); fputc('\n', stderr);
} }
exit(1);
} }
void void
@ -514,10 +481,10 @@ advance(const Arg *arg)
slides[idx].img->state &= ~(DRAWN | SCALED); slides[idx].img->state &= ~(DRAWN | SCALED);
idx = new_idx; idx = new_idx;
xdraw(); xdraw();
if (slidecount > idx + 1 && slides[idx + 1].img && !ffread(slides[idx + 1].img)) if (slidecount > idx + 1 && slides[idx + 1].img)
die("Unable to read image %s", slides[idx + 1].lines[0]); ffread(slides[idx + 1].img);
if (0 < idx && slides[idx - 1].img && !ffread(slides[idx - 1].img)) if (0 < idx && slides[idx - 1].img)
die("Unable to read image %s", slides[idx - 1].lines[0]); ffread(slides[idx - 1].img);
} }
} }
@ -559,13 +526,6 @@ run()
} }
} }
void
usage()
{
die("sent " VERSION " (c) 2014-2015 markus.teich@stusta.mhn.de\n" \
"usage: sent FILE1 [FILE2 ...]", argv0);
}
void void
xdraw() xdraw()
{ {
@ -586,11 +546,12 @@ xdraw()
slides[idx].lines[i], slides[idx].lines[i],
0); 0);
drw_map(d, xw.win, 0, 0, xw.w, xw.h); drw_map(d, xw.win, 0, 0, xw.w, xw.h);
} else if (!(im->state & LOADED) && !ffread(im)) { } else {
eprintf("Unable to read image %s", slides[idx].lines[0]); if (!(im->state & LOADED))
} else if (!(im->state & SCALED) && !ffprepare(im)) { ffread(im);
eprintf("Unable to prepare image %s for drawing", slides[idx].lines[0]); if (!(im->state & SCALED))
} else if (!(im->state & DRAWN)) { ffprepare(im);
if (!(im->state & DRAWN))
ffdraw(im); ffdraw(im);
} }
} }
@ -724,6 +685,13 @@ configure(XEvent *e)
xdraw(); xdraw();
} }
void
usage()
{
die("sent " VERSION " (c) 2014-2015 markus.teich@stusta.mhn.de\n" \
"usage: sent FILE1 [FILE2 ...]", argv0);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
@ -741,7 +709,7 @@ main(int argc, char *argv[])
load(fp); load(fp);
fclose(fp); fclose(fp);
} else { } else {
eprintf("Unable to open '%s' for reading:", argv[i]); die("Unable to open '%s' for reading:", argv[i]);
} }
} }