tsync updated drw code from dmenu - dwm - [fork] customized build of dwm, the d… | |
git clone git://src.adamsgaard.dk/dwm | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 646b351cc79845f4cc77415dfff474b9ae0053d9 | |
parent e3b7e1d620e18818222c1e5033356ae29dd49e7f | |
Author: Hiltjo Posthuma <[email protected]> | |
Date: Tue, 20 Oct 2015 23:34:49 +0200 | |
sync updated drw code from dmenu | |
important: | |
- drw_rect: didn't use w and h, change the dwm code accordingly. | |
- drw_text: text is NULL is not allowed, use drw_rect(). | |
Diffstat: | |
M drw.c | 251 +++++++++++++++--------------… | |
M drw.h | 34 ++++++++++++++++-------------… | |
M dwm.c | 10 ++++++---- | |
M util.c | 26 +++++++++++++++++++++----- | |
M util.h | 1 + | |
5 files changed, 164 insertions(+), 158 deletions(-) | |
--- | |
diff --git a/drw.c b/drw.c | |
t@@ -9,7 +9,7 @@ | |
#include "util.h" | |
#define UTF_INVALID 0xFFFD | |
-#define UTF_SIZ 4 | |
+#define UTF_SIZ 4 | |
static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF… | |
static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF… | |
t@@ -17,50 +17,55 @@ static const long utfmin[UTF_SIZ + 1] = { 0, 0, … | |
static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FF… | |
static long | |
-utf8decodebyte(const char c, size_t *i) { | |
- for(*i = 0; *i < (UTF_SIZ + 1); ++(*i)) | |
- if(((unsigned char)c & utfmask[*i]) == utfbyte[*i]) | |
+utf8decodebyte(const char c, size_t *i) | |
+{ | |
+ for (*i = 0; *i < (UTF_SIZ + 1); ++(*i)) | |
+ if (((unsigned char)c & utfmask[*i]) == utfbyte[*i]) | |
return (unsigned char)c & ~utfmask[*i]; | |
return 0; | |
} | |
static size_t | |
-utf8validate(long *u, size_t i) { | |
- if(!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) | |
+utf8validate(long *u, size_t i) | |
+{ | |
+ if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) | |
*u = UTF_INVALID; | |
- for(i = 1; *u > utfmax[i]; ++i) | |
+ for (i = 1; *u > utfmax[i]; ++i) | |
; | |
return i; | |
} | |
static size_t | |
-utf8decode(const char *c, long *u, size_t clen) { | |
+utf8decode(const char *c, long *u, size_t clen) | |
+{ | |
size_t i, j, len, type; | |
long udecoded; | |
*u = UTF_INVALID; | |
- if(!clen) | |
+ if (!clen) | |
return 0; | |
udecoded = utf8decodebyte(c[0], &len); | |
- if(!BETWEEN(len, 1, UTF_SIZ)) | |
+ if (!BETWEEN(len, 1, UTF_SIZ)) | |
return 1; | |
- for(i = 1, j = 1; i < clen && j < len; ++i, ++j) { | |
+ for (i = 1, j = 1; i < clen && j < len; ++i, ++j) { | |
udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type); | |
- if(type != 0) | |
+ if (type) | |
return j; | |
} | |
- if(j < len) | |
+ if (j < len) | |
return 0; | |
*u = udecoded; | |
utf8validate(u, len); | |
+ | |
return len; | |
} | |
Drw * | |
-drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int… | |
- Drw *drw = (Drw *)calloc(1, sizeof(Drw)); | |
- if(!drw) | |
- return NULL; | |
+drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int… | |
+{ | |
+ Drw *drw; | |
+ | |
+ drw = ecalloc(1, sizeof(Drw)); | |
drw->dpy = dpy; | |
drw->screen = screen; | |
drw->root = root; | |
t@@ -70,26 +75,27 @@ drw_create(Display *dpy, int screen, Window root, unsigned… | |
drw->gc = XCreateGC(dpy, root, 0, NULL); | |
drw->fontcount = 0; | |
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); | |
+ | |
return drw; | |
} | |
void | |
-drw_resize(Drw *drw, unsigned int w, unsigned int h) { | |
- if(!drw) | |
- return; | |
+drw_resize(Drw *drw, unsigned int w, unsigned int h) | |
+{ | |
drw->w = w; | |
drw->h = h; | |
- if(drw->drawable != 0) | |
+ if (drw->drawable) | |
XFreePixmap(drw->dpy, drw->drawable); | |
drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(… | |
} | |
void | |
-drw_free(Drw *drw) { | |
+drw_free(Drw *drw) | |
+{ | |
size_t i; | |
- for (i = 0; i < drw->fontcount; i++) { | |
+ | |
+ for (i = 0; i < drw->fontcount; i++) | |
drw_font_free(drw->fonts[i]); | |
- } | |
XFreePixmap(drw->dpy, drw->drawable); | |
XFreeGC(drw->dpy, drw->gc); | |
free(drw); | |
t@@ -99,14 +105,11 @@ drw_free(Drw *drw) { | |
* drw_font_create instead. | |
*/ | |
static Fnt * | |
-drw_font_xcreate(Drw *drw, const char *fontname, FcPattern *fontpattern) { | |
+drw_font_xcreate(Drw *drw, const char *fontname, FcPattern *fontpattern) | |
+{ | |
Fnt *font; | |
- | |
- if (!(fontname || fontpattern)) | |
- die("No font specified.\n"); | |
- | |
- if (!(font = (Fnt *)calloc(1, sizeof(Fnt)))) | |
- return NULL; | |
+ XftFont *xfont = NULL; | |
+ FcPattern *pattern = NULL; | |
if (fontname) { | |
/* Using the pattern found at font->xfont->pattern does not yi… | |
t@@ -115,46 +118,50 @@ drw_font_xcreate(Drw *drw, const char *fontname, FcPatte… | |
* behaviour whereas the former just results in | |
* missing-character-rectangles being drawn, at least with som… | |
*/ | |
- if (!(font->xfont = XftFontOpenName(drw->dpy, drw->screen, fon… | |
- !(font->pattern = FcNameParse((FcChar8 *) fontname))) { | |
- if (font->xfont) { | |
- XftFontClose(drw->dpy, font->xfont); | |
- font->xfont = NULL; | |
- } | |
+ if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname)… | |
fprintf(stderr, "error, cannot load font: '%s'\n", fon… | |
+ return NULL; | |
+ } | |
+ if (!(pattern = FcNameParse((FcChar8 *) fontname))) { | |
+ fprintf(stderr, "error, cannot load font: '%s'\n", fon… | |
+ XftFontClose(drw->dpy, xfont); | |
+ return NULL; | |
} | |
} else if (fontpattern) { | |
- if (!(font->xfont = XftFontOpenPattern(drw->dpy, fontpattern))… | |
+ if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { | |
fprintf(stderr, "error, cannot load font pattern.\n"); | |
- } else { | |
- font->pattern = NULL; | |
+ return NULL; | |
} | |
+ } else { | |
+ die("no font specified.\n"); | |
} | |
- if (!font->xfont) { | |
- free(font); | |
- return NULL; | |
- } | |
- | |
- font->ascent = font->xfont->ascent; | |
- font->descent = font->xfont->descent; | |
+ font = ecalloc(1, sizeof(Fnt)); | |
+ font->xfont = xfont; | |
+ font->pattern = pattern; | |
+ font->ascent = xfont->ascent; | |
+ font->descent = xfont->descent; | |
font->h = font->ascent + font->descent; | |
font->dpy = drw->dpy; | |
+ | |
return font; | |
} | |
Fnt* | |
-drw_font_create(Drw *drw, const char *fontname) { | |
+drw_font_create(Drw *drw, const char *fontname) | |
+{ | |
return drw_font_xcreate(drw, fontname, NULL); | |
} | |
void | |
-drw_load_fonts(Drw* drw, const char *fonts[], size_t fontcount) { | |
+drw_load_fonts(Drw* drw, const char *fonts[], size_t fontcount) | |
+{ | |
size_t i; | |
Fnt *font; | |
+ | |
for (i = 0; i < fontcount; i++) { | |
if (drw->fontcount >= DRW_FONT_CACHE_SIZE) { | |
- die("Font cache exhausted.\n"); | |
+ die("font cache exhausted.\n"); | |
} else if ((font = drw_font_xcreate(drw, fonts[i], NULL))) { | |
drw->fonts[drw->fontcount++] = font; | |
} | |
t@@ -162,68 +169,62 @@ drw_load_fonts(Drw* drw, const char *fonts[], size_t fon… | |
} | |
void | |
-drw_font_free(Fnt *font) { | |
- if(!font) | |
+drw_font_free(Fnt *font) | |
+{ | |
+ if (!font) | |
return; | |
- if(font->pattern) | |
+ if (font->pattern) | |
FcPatternDestroy(font->pattern); | |
XftFontClose(font->dpy, font->xfont); | |
free(font); | |
} | |
Clr * | |
-drw_clr_create(Drw *drw, const char *clrname) { | |
+drw_clr_create(Drw *drw, const char *clrname) | |
+{ | |
Clr *clr; | |
- Colormap cmap; | |
- Visual *vis; | |
- | |
- if(!drw) | |
- return NULL; | |
- clr = (Clr *)calloc(1, sizeof(Clr)); | |
- if(!clr) | |
- return NULL; | |
- cmap = DefaultColormap(drw->dpy, drw->screen); | |
- vis = DefaultVisual(drw->dpy, drw->screen); | |
- if(!XftColorAllocName(drw->dpy, vis, cmap, clrname, &clr->rgb)) | |
+ | |
+ clr = ecalloc(1, sizeof(Clr)); | |
+ if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), | |
+ DefaultColormap(drw->dpy, drw->screen), | |
+ clrname, &clr->rgb)) | |
die("error, cannot allocate color '%s'\n", clrname); | |
clr->pix = clr->rgb.pixel; | |
+ | |
return clr; | |
} | |
void | |
-drw_clr_free(Clr *clr) { | |
- if(clr) | |
- free(clr); | |
+drw_clr_free(Clr *clr) | |
+{ | |
+ free(clr); | |
} | |
void | |
-drw_setscheme(Drw *drw, ClrScheme *scheme) { | |
- if(drw && scheme) | |
- drw->scheme = scheme; | |
+drw_setscheme(Drw *drw, ClrScheme *scheme) | |
+{ | |
+ drw->scheme = scheme; | |
} | |
void | |
-drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, i… | |
- int dx; | |
- | |
- if(!drw || !drw->fontcount || !drw->scheme) | |
+drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, i… | |
+{ | |
+ if (!drw->scheme) | |
return; | |
XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->bg->pix : drw-… | |
- dx = (drw->fonts[0]->ascent + drw->fonts[0]->descent + 2) / 4; | |
- if(filled) | |
- XFillRectangle(drw->dpy, drw->drawable, drw->gc, x+1, y+1, dx+… | |
- else if(empty) | |
- XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x+1, y+1, dx,… | |
+ if (filled) | |
+ XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w + 1, … | |
+ else if (empty) | |
+ XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); | |
} | |
int | |
-drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *t… | |
+drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *t… | |
+{ | |
char buf[1024]; | |
int tx, ty, th; | |
Extnts tex; | |
- Colormap cmap; | |
- Visual *vis; | |
- XftDraw *d; | |
+ XftDraw *d = NULL; | |
Fnt *curfont, *nextfont; | |
size_t i, len; | |
int utf8strlen, utf8charlen, render; | |
t@@ -235,23 +236,18 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigne… | |
XftResult result; | |
int charexists = 0; | |
+ if (!drw->scheme || !drw->fontcount) | |
+ return 0; | |
+ | |
if (!(render = x || y || w || h)) { | |
w = ~w; | |
- } | |
- | |
- if (!drw || !drw->scheme) { | |
- return 0; | |
- } else if (render) { | |
- XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme->fg->pi… | |
+ } else { | |
+ XSetForeground(drw->dpy, drw->gc, invert ? | |
+ drw->scheme->fg->pix : drw->scheme->bg->pix); | |
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); | |
- } | |
- | |
- if (!text || !drw->fontcount) { | |
- return 0; | |
- } else if (render) { | |
- cmap = DefaultColormap(drw->dpy, drw->screen); | |
- vis = DefaultVisual(drw->dpy, drw->screen); | |
- d = XftDrawCreate(drw->dpy, drw->drawable, vis, cmap); | |
+ d = XftDrawCreate(drw->dpy, drw->drawable, | |
+ DefaultVisual(drw->dpy, drw->screen), | |
+ DefaultColormap(drw->dpy, drw->screen)); | |
} | |
curfont = drw->fonts[0]; | |
t@@ -274,24 +270,23 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigne… | |
} | |
} | |
- if (!charexists || (nextfont && nextfont != curfont)) { | |
+ if (!charexists || (nextfont && nextfont != curfont)) | |
break; | |
- } else { | |
+ else | |
charexists = 0; | |
- } | |
} | |
if (utf8strlen) { | |
drw_font_getexts(curfont, utf8str, utf8strlen, &tex); | |
/* shorten text if necessary */ | |
- for(len = MIN(utf8strlen, (sizeof buf) - 1); len && (t… | |
+ for (len = MIN(utf8strlen, (sizeof buf) - 1); len && (… | |
drw_font_getexts(curfont, utf8str, len, &tex); | |
if (len) { | |
memcpy(buf, utf8str, len); | |
buf[len] = '\0'; | |
- if(len < utf8strlen) | |
- for(i = len; i && i > len - 3; buf[--i… | |
+ if (len < utf8strlen) | |
+ for (i = len; i && i > len - 3; buf[--… | |
if (render) { | |
th = curfont->ascent + curfont->descen… | |
t@@ -299,7 +294,6 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned … | |
tx = x + (h / 2); | |
XftDrawStringUtf8(d, invert ? &drw->sc… | |
} | |
- | |
x += tex.w; | |
w -= tex.w; | |
} | |
t@@ -316,18 +310,16 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigne… | |
*/ | |
charexists = 1; | |
- if (drw->fontcount >= DRW_FONT_CACHE_SIZE) { | |
+ if (drw->fontcount >= DRW_FONT_CACHE_SIZE) | |
continue; | |
- } | |
fccharset = FcCharSetCreate(); | |
FcCharSetAddChar(fccharset, utf8codepoint); | |
if (!drw->fonts[0]->pattern) { | |
/* Refer to the comment in drw_font_xcreate fo… | |
- * information. | |
- */ | |
- die("The first font in the cache must be loade… | |
+ * information. */ | |
+ die("the first font in the cache must be loade… | |
} | |
fcpattern = FcPatternDuplicate(drw->fonts[0]->pattern); | |
t@@ -346,65 +338,60 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigne… | |
if (curfont && XftCharExists(drw->dpy, curfont… | |
drw->fonts[drw->fontcount++] = curfont; | |
} else { | |
- if (curfont) { | |
- drw_font_free(curfont); | |
- } | |
+ drw_font_free(curfont); | |
curfont = drw->fonts[0]; | |
} | |
} | |
} | |
} | |
- | |
- if (render) { | |
+ if (d) | |
XftDrawDestroy(d); | |
- } | |
return x; | |
} | |
void | |
-drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) { | |
- if(!drw) | |
- return; | |
+drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) | |
+{ | |
XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y); | |
XSync(drw->dpy, False); | |
} | |
- | |
void | |
-drw_font_getexts(Fnt *font, const char *text, unsigned int len, Extnts *tex) { | |
+drw_font_getexts(Fnt *font, const char *text, unsigned int len, Extnts *tex) | |
+{ | |
XGlyphInfo ext; | |
- if(!font || !text) | |
- return; | |
XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext… | |
tex->h = font->h; | |
tex->w = ext.xOff; | |
} | |
unsigned int | |
-drw_font_getexts_width(Fnt *font, const char *text, unsigned int len) { | |
+drw_font_getexts_width(Fnt *font, const char *text, unsigned int len) | |
+{ | |
Extnts tex; | |
- if(!font) | |
- return -1; | |
drw_font_getexts(font, text, len, &tex); | |
+ | |
return tex.w; | |
} | |
Cur * | |
-drw_cur_create(Drw *drw, int shape) { | |
- Cur *cur = (Cur *)calloc(1, sizeof(Cur)); | |
+drw_cur_create(Drw *drw, int shape) | |
+{ | |
+ Cur *cur; | |
- if(!drw || !cur) | |
- return NULL; | |
+ cur = ecalloc(1, sizeof(Cur)); | |
cur->cursor = XCreateFontCursor(drw->dpy, shape); | |
+ | |
return cur; | |
} | |
void | |
-drw_cur_free(Drw *drw, Cur *cursor) { | |
- if(!drw || !cursor) | |
+drw_cur_free(Drw *drw, Cur *cursor) | |
+{ | |
+ if (!cursor) | |
return; | |
XFreeCursor(drw->dpy, cursor->cursor); | |
free(cursor); | |
diff --git a/drw.h b/drw.h | |
t@@ -43,32 +43,32 @@ typedef struct { | |
} Extnts; | |
/* Drawable abstraction */ | |
-Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned… | |
-void drw_resize(Drw *drw, unsigned int w, unsigned int h); | |
-void drw_free(Drw *drw); | |
+Drw *drw_create(Display *, int, Window, unsigned int, unsigned int); | |
+void drw_resize(Drw *, unsigned int, unsigned int); | |
+void drw_free(Drw *); | |
/* Fnt abstraction */ | |
-Fnt *drw_font_create(Drw *drw, const char *fontname); | |
-void drw_load_fonts(Drw* drw, const char *fonts[], size_t fontcount); | |
-void drw_font_free(Fnt *font); | |
-void drw_font_getexts(Fnt *font, const char *text, unsigned int len, Extnts *e… | |
-unsigned int drw_font_getexts_width(Fnt *font, const char *text, unsigned int … | |
+Fnt *drw_font_create(Drw *, const char *); | |
+void drw_load_fonts(Drw *, const char *[], size_t); | |
+void drw_font_free(Fnt *); | |
+void drw_font_getexts(Fnt *, const char *, unsigned int, Extnts *); | |
+unsigned int drw_font_getexts_width(Fnt *, const char *, unsigned int); | |
/* Colour abstraction */ | |
-Clr *drw_clr_create(Drw *drw, const char *clrname); | |
-void drw_clr_free(Clr *clr); | |
+Clr *drw_clr_create(Drw *, const char *); | |
+void drw_clr_free(Clr *); | |
/* Cursor abstraction */ | |
-Cur *drw_cur_create(Drw *drw, int shape); | |
-void drw_cur_free(Drw *drw, Cur *cursor); | |
+Cur *drw_cur_create(Drw *, int); | |
+void drw_cur_free(Drw *, Cur *); | |
/* Drawing context manipulation */ | |
-void drw_setfont(Drw *drw, Fnt *font); | |
-void drw_setscheme(Drw *drw, ClrScheme *scheme); | |
+void drw_setfont(Drw *, Fnt *); | |
+void drw_setscheme(Drw *, ClrScheme *); | |
/* Drawing functions */ | |
-void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int fill… | |
-int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, const cha… | |
+void drw_rect(Drw *, int, int, unsigned int, unsigned int, int, int, int); | |
+int drw_text(Drw *, int, int, unsigned int, unsigned int, const char *, int); | |
/* Map functions */ | |
-void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int … | |
+void drw_map(Drw *, Window, int, int, unsigned int, unsigned int); | |
diff --git a/dwm.c b/dwm.c | |
t@@ -689,10 +689,12 @@ dirtomon(int dir) { | |
void | |
drawbar(Monitor *m) { | |
- int x, xx, w; | |
+ int x, xx, w, dx; | |
unsigned int i, occ = 0, urg = 0; | |
Client *c; | |
+ dx = (drw->fonts[0]->ascent + drw->fonts[0]->descent + 2) / 4; | |
+ | |
for(c = m->clients; c; c = c->next) { | |
occ |= c->tags; | |
if(c->isurgent) | |
t@@ -703,7 +705,7 @@ drawbar(Monitor *m) { | |
w = TEXTW(tags[i]); | |
drw_setscheme(drw, m->tagset[m->seltags] & 1 << i ? &scheme[Sc… | |
drw_text(drw, x, 0, w, bh, tags[i], urg & 1 << i); | |
- drw_rect(drw, x, 0, w, bh, m == selmon && selmon->sel && selmo… | |
+ drw_rect(drw, x + 1, 1, dx, dx, m == selmon && selmon->sel && … | |
occ & 1 << i, urg & 1 << i); | |
x += w; | |
} | |
t@@ -728,11 +730,11 @@ drawbar(Monitor *m) { | |
if(m->sel) { | |
drw_setscheme(drw, m == selmon ? &scheme[SchemeSel] : … | |
drw_text(drw, x, 0, w, bh, m->sel->name, 0); | |
- drw_rect(drw, x, 0, w, bh, m->sel->isfixed, m->sel->is… | |
+ drw_rect(drw, x + 1, 1, dx, dx, m->sel->isfixed, m->se… | |
} | |
else { | |
drw_setscheme(drw, &scheme[SchemeNorm]); | |
- drw_text(drw, x, 0, w, bh, NULL, 0); | |
+ drw_rect(drw, x, 0, w, bh, 1, 0, 1); | |
} | |
} | |
drw_map(drw, m->barwin, 0, 0, m->ww, bh); | |
diff --git a/util.c b/util.c | |
t@@ -2,16 +2,32 @@ | |
#include <stdarg.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
+#include <string.h> | |
#include "util.h" | |
+void * | |
+ecalloc(size_t nmemb, size_t size) | |
+{ | |
+ void *p; | |
+ | |
+ if (!(p = calloc(nmemb, size))) | |
+ perror(NULL); | |
+ return p; | |
+} | |
+ | |
void | |
-die(const char *errstr, ...) { | |
+die(const char *fmt, ...) { | |
va_list ap; | |
- va_start(ap, errstr); | |
- vfprintf(stderr, errstr, ap); | |
+ va_start(ap, fmt); | |
+ vfprintf(stderr, fmt, ap); | |
va_end(ap); | |
- exit(EXIT_FAILURE); | |
-} | |
+ if (fmt[0] && fmt[strlen(fmt)-1] == ':') { | |
+ fputc(' ', stderr); | |
+ perror(NULL); | |
+ } | |
+ | |
+ exit(1); | |
+} | |
diff --git a/util.h b/util.h | |
t@@ -5,3 +5,4 @@ | |
#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B)) | |
void die(const char *errstr, ...); | |
+void *ecalloc(size_t, size_t); |