Commit Diff


commit - 416a28cd15d653debef9a718562becd08f146d77
commit + 3d89457cdeba5041aa6f0c1f8640b91bcbb6ec51
blob - 7147d48986f40aa0e63204363d6abd0b4eed8238
blob + 53f52a7e82ab528e0782e67d60d2c5fa23e50afe
--- Makefile.am
+++ Makefile.am
@@ -65,7 +65,9 @@ telescope_SOURCES =	bufio.c			\
 			utf8.h			\
 			utils.c			\
 			utils.h			\
-			wrap.c
+			wrap.c 			\
+			xwrapper.c 		\
+			xwrapper.h
 
 telescope_identity_SOURCES =			\
 			certs.c			\
@@ -76,11 +78,33 @@ telescope_identity_SOURCES =			\
 			hist.h			\
 			identity.c		\
 			parser.c		\
-			parser.h
+			parser.h 		\
+			xwrapper.c 		\
+			xwrapper.h
 
 noinst_PROGRAMS =	pagebundler
 pagebundler_SOURCES =	pagebundler.c
 
+EXCLUDE_FROM_COCCI=	bufio.c 		\
+			certs.c 		\
+			cmd-gen.c 		\
+			emoji-matcher.c 	\
+			ev.c 			\
+			hist.c 			\
+			pages.c			\
+			parse.c 		\
+			xwrapper.c
+EXTS= 			.c .y
+
+SPATCH_FILES = $(foreach ext,$(EXTS),$(filter %$(ext), 			\
+	       $(filter-out $(EXCLUDE_FROM_COCCI), 			\
+	       $(telescope_SOURCES), $(telescope_identity_SOURCES), 	\
+	       $(wilcard test/*.c))))
+.PHONY: cocci
+cocci:
+	spatch  --sp-file ./contrib/coccinelle/wrap.cocci \
+		--in-place $(SPATCH_FILES)
+
 # Override implicit rule since we have to use HOSTCC and not CC.
 pagebundler$(EXEEXT): pagebundler.c
 	$(HOSTCC) $(HOSTCFLAGS) -o $@ $(srcdir)/pagebundler.c
blob - 88f81d8d52882726aa57ecbd2c1d9830f48823c5
blob + 2a6b8e0443963f948448ef1a28bc8db64e6186d4
--- contrib/README.md
+++ contrib/README.md
@@ -9,3 +9,4 @@
    `~/.config/telescope/config`
  - `xdg-migrate.sh` aids the migration from a monolithic
    `~/.telescope` directory to a XDG.
+ - `coccinelle/` contains cocci scripts used for code transformation.
blob - /dev/null
blob + 21485de092a0e80a152c18cefa57769a3a8c6be8 (mode 644)
--- /dev/null
+++ contrib/coccinelle/wrap.cocci
@@ -0,0 +1,91 @@
+@@
+expression x, y;
+statement S;
+@@
+-if ((x = strdup(y)) == NULL)
+- S
++x = xstrdup(y);
+
+@@
+expression x, y;
+statement S;
+@@
+-x = strdup(y);
+-if (x == NULL)
+- S
++x = xstrdup(y);
+
+@@
+expression x, y;
+@@
+-x = strdup(y);
++x = xstrdup(y);
+
+@@
+expression x, y, z;
+statement S;
+@@
+-if ((x = strndup(y, z)) == NULL)
+- S
++x = xstrndup(y, z);
+
+@@
+expression x, y;
+statement S;
+@@
+-if ((x = malloc(y)) == NULL)
+- S
++x = xmalloc(y);
+
+@@
+expression x, y, z;
+statement S;
+@@
+-if ((x = calloc(y, z)) == NULL)
+- S
++x = xcalloc(y, z);
+
+@@
+expression x, y, z;
+statement S;
+@@
+-if ((x = realloc(y, z)) == NULL)
+- S
++x = xrealloc(y, z);
+
+@@
+expression x, y, z;
+statement S;
+@@
+-x = realloc(y, z);
+- S
++x = xrealloc(y, z);
+
+@@
+expression w, x, y, z;
+statement S;
+@@
+-if ((x = reallocarray(w, y, z)) == NULL)
+- S
++x = xreallocarray(w, y, z);
+
+@@
+expression w, x, y, z;
+@@
+-x = reallocarray(w, y, z);
++x = xreallocarray(w, y, z);
+
+@@
+expression fmt;
+expression list args;
+statement S;
+@@
+-if (asprintf(fmt, args) == -1) S
++xasprintf(fmt, args);
+
+@@
+expression x, fmt;
+expression list args;
+@@
+-x = asprintf(fmt, args);
++xasprintf(fmt, args);
blob - 6522d2b5fb0a86b9ed02653d5fa1f959bae735d9
blob + 65a705971ea2f9a254dbf0dcbf208401bd9e2d2d
--- control.c
+++ control.c
@@ -36,6 +36,7 @@
 #include "telescope.h"
 #include "utils.h"
 #include "ui.h"
+#include "xwrapper.h"
 
 #define	CONTROL_BACKLOG	5
 
@@ -152,11 +153,7 @@ control_accept(int listenfd, int event, void *bula)
 		return;
 	}
 
-	if ((c = calloc(1, sizeof(struct ctl_conn))) == NULL) {
-		message("%s: calloc: %s", __func__, strerror(errno));
-		close(connfd);
-		return;
-	}
+	c = xcalloc(1, sizeof(struct ctl_conn));
 
 	imsg_init(&c->iev.ibuf, connfd);
 	c->iev.handler = control_dispatch_imsg;
blob - b412c417343219fb305754e53997eaf01ec7e8ef
blob + f25cda82fef17a6009033c6e81c165d48706e950
--- defaults.c
+++ defaults.c
@@ -28,6 +28,7 @@
 #include "telescope.h"
 #include "ui.h"
 #include "utils.h"
+#include "xwrapper.h"
 
 char	*default_protocol = NULL;
 char	*download_path = NULL;
@@ -539,9 +540,7 @@ config_init(void)
 	struct line_face *f;
 	size_t i, len;
 
-	default_search_engine = strdup("gemini://kennedy.gemi.dev/search");
-	if (default_search_engine == NULL)
-		err(1, "strdup");
+	default_search_engine = xstrdup("gemini://kennedy.gemi.dev/search");
 
 	len = sizeof(line_faces)/sizeof(line_faces[0]);
 	for (i = 0; i < len; ++i) {
@@ -639,10 +638,7 @@ config_setvars(const char *var, char *val)
 			sufx = "/";
 
 		free(download_path);
-		if (asprintf(&download_path, "%s%s%s", prfx, v, sufx) == -1) {
-			download_path = NULL;
-			return 0;
-		}
+		xasprintf(&download_path, "%s%s%s", prfx, v, sufx);
 
 		free(val);
 		return 1;
blob - d170814554742461eb57783379f97b67f08ea61c
blob + 55e409f587dd8e950bd3e92ff391b43de995028d
--- downloads.c
+++ downloads.c
@@ -22,6 +22,7 @@
 
 #include "telescope.h"
 #include "ui.h"
+#include "xwrapper.h"
 
 struct downloads downloads = STAILQ_HEAD_INITIALIZER(downloads);
 
@@ -30,11 +31,10 @@ no_downloads(void)
 {
 	struct line	*l;
 
-	if ((l = calloc(1, sizeof(*l))) == NULL)
-		abort();
+	l = xcalloc(1, sizeof(*l));
 
 	l->type = LINE_DOWNLOAD_INFO;
-	l->line = strdup("No downloads");
+	l->line = xstrdup("No downloads");
 
 	TAILQ_INSERT_TAIL(&downloadwin.head, l, lines);
 }
@@ -55,8 +55,7 @@ recompute_downloads(void)
 	}
 
 	STAILQ_FOREACH(d, &downloads, entries) {
-		if ((l = calloc(1, sizeof(*l))) == NULL)
-			abort();
+		l = xcalloc(1, sizeof(*l));
 
 		fmt_scaled(d->bytes, buf);
 
@@ -64,8 +63,8 @@ recompute_downloads(void)
 		if (d->fd == -1)
 			l->type = LINE_DOWNLOAD_DONE;
 
-		l->line = strdup(buf);
-		l->alt = strdup(d->path);
+		l->line = xstrdup(buf);
+		l->alt = xstrdup(d->path);
 
 		TAILQ_INSERT_TAIL(&downloadwin.head, l, lines);
 	}
@@ -85,13 +84,12 @@ enqueue_download(uint32_t id, const char *path, const 
 {
 	struct download *d;
 
-	if ((d = calloc(1, sizeof(*d))) == NULL)
-		abort();
+	d = xcalloc(1, sizeof(*d));
 
 	d->id = id;
 	d->fd = -1;
-	d->path = strdup(path);
-	d->mime_type = strdup(mime_type);
+	d->path = xstrdup(path);
+	d->mime_type = xstrdup(mime_type);
 
 	STAILQ_INSERT_HEAD(&downloads, d, entries);
 
blob - 0a13259a4b223644c7aacff979f4156a200fc534
blob + 0ea7d7de312b026d9dd4c0d4d5e123e001509732
--- fs.c
+++ fs.c
@@ -98,8 +98,7 @@ send_dir(struct tab *tab, const char *path)
 	 */
 
 	if (!has_suffix(path, "/")) {
-		if (asprintf(&s, "%s/", path) == -1)
-			die();
+		xasprintf(&s, "%s/", path);
 		send_hdr(peerid, 30, s);
 		free(s);
 		return;
blob - 2d4a687fef96e329ef2414b0400715e5126f2124
blob + a71194801bebd6854ad8374b707c970a667e9e9d
--- help.c
+++ help.c
@@ -25,6 +25,7 @@
 #include "keymap.h"
 #include "telescope.h"
 #include "ui.h"
+#include "xwrapper.h"
 
 static void	emit_help_item(char *, interactivefn *);
 static void	rec_compute_help(struct kmap *, char *, size_t);
@@ -41,11 +42,10 @@ emit_help_item(char *prfx, interactivefn *fn)
 	}
 	assert(cmd != NULL);
 
-	if ((l = calloc(1, sizeof(*l))) == NULL)
-		abort();
+	l = xcalloc(1, sizeof(*l));
 
 	l->type = LINE_HELP;
-	l->line = strdup(prfx);
+	l->line = xstrdup(prfx);
 	l->alt = (char*)cmd->cmd;
 
 	TAILQ_INSERT_TAIL(&helpwin.head, l, lines);
blob - 15ee034088cb08ab0293ff28ce1fe11446b7a79b
blob + 5e5b35885d969e33b0debd77d022a57a7b530393
--- keymap.c
+++ keymap.c
@@ -23,6 +23,7 @@
 
 #include "keymap.h"
 #include "utils.h"
+#include "xwrapper.h"
 
 #define CTRL(n)	((n)&0x1F)
 
@@ -178,8 +179,7 @@ again:
 		}
 	}
 
-	if ((entry = calloc(1, sizeof(*entry))) == NULL)
-		return 0;
+	entry = xcalloc(1, sizeof(*entry));
 
 	entry->meta = meta;
 	entry->key = k;
blob - 9f549357ab7fcb8bbd7389b7855b688de9d95cfe
blob + a44a7799d6e7bd0b97335f28cbc9bb96dfbe8dfe
--- mailcap.c
+++ mailcap.c
@@ -30,6 +30,7 @@
 
 #include "compat.h"
 #include "mailcap.h"
+#include "xwrapper.h"
 
 #define DEFAULT_MAILCAP_ENTRY "*/*; xdg-open %s"
 
@@ -93,7 +94,7 @@ str_append(char **buf, size_t *len, char add)
 	if (al > SIZE_MAX - 1 || *len > SIZE_MAX - 1 - al)
 		errx(1, "buffer is too big");
 
-	*buf = realloc(*buf, (*len) + 1 + al);
+	*buf = xrealloc(*buf, (*len) + 1 + al);
 	memcpy((*buf) + *len, &add, al);
 	(*len) += al;
 }
@@ -222,8 +223,7 @@ str_to_argv(char *str, int *ret_argc, char ***ret_argv
 		return -1;
 
 	free(sps.buf);
-	if ((sps.buf = strdup(str)) == NULL)
-		errx(1, "strdup");
+	sps.buf = xstrdup(str);
 	sps.len = strlen(sps.buf);
 
 	for (;;) {
@@ -253,9 +253,8 @@ str_to_argv(char *str, int *ret_argc, char ***ret_argv
 		}
 
 		/* Add to argv. */
-		argv = reallocarray(argv, argc + 1, sizeof *argv);
-		if ((argv[argc++] = strdup(token)) == NULL)
-			errx(1, "strdup");
+		argv = xreallocarray(argv, argc + 1, sizeof *argv);
+		argv[argc++] = xstrdup(token);
 	}
 out:
 	*ret_argv = argv;
@@ -307,8 +306,7 @@ mailcap_new(void)
 {
 	struct mailcap	*mc = NULL;
 
-	if ((mc = calloc(1, sizeof *mc)) == NULL)
-		errx(1, "calloc failed");
+	mc = xcalloc(1, sizeof *mc);
 
 	return (mc);
 }
@@ -327,13 +325,11 @@ parse_mailcap_line(char *input)
 
 		switch (ms) {
 		case MAILCAP_MIME:
-			if ((mc->mime_type = strdup(line)) == NULL)
-				errx(1, "strdup");
+			mc->mime_type = xstrdup(line);
 			ms++;
 			break;
 		case MAILCAP_CMD:
-			if ((mc->cmd = strdup(line)) == NULL)
-				errx(1, "strdup");
+			mc->cmd = xstrdup(line);
 			ms++;
 			break;
 		case MAILCAP_FLAGS:
@@ -372,14 +368,12 @@ mailcap_expand_cmd(struct mailcap *mc, char *mt, char 
 	for (int z = 0; z < argc; z++) {
 		if (strcmp(argv[z], "%s") == 0) {
 			free(argv[z]);
-			if ((argv[z] = strdup(file)) == NULL)
-				errx(1, "strdup");
+			argv[z] = xstrdup(file);
 		}
 
 		if (strcmp(argv[z], "%t") == 0) {
 			free(argv[z]);
-			if ((argv[z] = strdup(mt)) == NULL)
-				errx(1, "strdup");
+			argv[z] = xstrdup(mt);
 		}
 	}
 	argv[argc++] = NULL;
@@ -413,8 +407,7 @@ init_mailcap(void)
 		fclose(f);
 	}
 
-	if ((copy = strdup(DEFAULT_MAILCAP_ENTRY)) == NULL)
-		errx(1, "strdup");
+	copy = xstrdup(DEFAULT_MAILCAP_ENTRY);
 
 	/* Our own entry won't error. */
 	(void)parse_mailcap_line(copy);
blob - 0e92a2adae57aa68d26f5f577c6b4cad5694191d
blob + d9c0cc7214e6bf5baa918485f9df02e06318a20e
--- mcache.c
+++ mcache.c
@@ -29,6 +29,7 @@
 #include "parser.h"
 #include "telescope.h"
 #include "utils.h"
+#include "xwrapper.h"
 
 static struct timeval tv = { 5 * 60, 0 };
 static unsigned int timeout;
@@ -106,8 +107,7 @@ mcache_tab(struct tab *tab)
 	l = strlen(url);
 	len = sizeof(*e) + l + 1;
 
-	if ((e = calloc(1, len)) == NULL)
-		return -1;
+	e = xcalloc(1, len);
 	e->ts = time(NULL);
 	e->parser = tab->buffer.parser;
 	e->trust = tab->trust;
blob - f830947eb8c2e60bd29e8fc8f7c293b003fc7d30
blob + 4b502acc02fdf47903bcbe1860135bc137a1753a
--- minibuffer.c
+++ minibuffer.c
@@ -38,6 +38,7 @@
 #include "ui.h"
 #include "utf8.h"
 #include "utils.h"
+#include "xwrapper.h"
 
 #define nitems(x) (sizeof(x)/sizeof(x[0]))
 
@@ -545,14 +546,12 @@ populate_compl_buffer(complfn *fn, void *data)
 	linedata = NULL;
 	descr = NULL;
 	while ((s = fn(&data, &linedata, &descr)) != NULL) {
-		if ((l = calloc(1, sizeof(*l))) == NULL)
-			abort();
+		l = xcalloc(1, sizeof(*l));
 
 		l->type = LINE_COMPL;
 		l->data = linedata;
 		l->alt = (char*)descr;
-		if ((l->line = strdup(s)) == NULL)
-			abort();
+		l->line = xstrdup(s);
 
 		TAILQ_INSERT_TAIL(&b->head, l, lines);
 
blob - 33d2cb68fbca9577634f246cd3b7294d3c36ea86
blob + b4095c8a50f78adc731e74dcccb649ed864cd84b
--- net.c
+++ net.c
@@ -42,6 +42,7 @@
 #include "imsgev.h"
 #include "telescope.h"
 #include "utils.h"
+#include "xwrapper.h"
 
 static struct imsgev		*iev_ui;
 
@@ -608,8 +609,7 @@ handle_dispatch_imsg(int fd, int event, void *d)
 			    r.proto != PROTO_GOPHER)
 				die();
 
-			if ((req = calloc(1, sizeof(*req))) == NULL)
-				die();
+			req = xcalloc(1, sizeof(*req));
 
 			req->fd = -1;
 #if HAVE_ASR_RUN
@@ -619,12 +619,9 @@ handle_dispatch_imsg(int fd, int event, void *d)
 			req->id = imsg_get_id(&imsg);
 			TAILQ_INSERT_HEAD(&reqhead, req, reqs);
 
-			if ((req->host = strdup(r.host)) == NULL)
-				die();
-			if ((req->port = strdup(r.port)) == NULL)
-				die();
-			if ((req->req = strdup(r.req)) == NULL)
-				die();
+			req->host = xstrdup(r.host);
+			req->port = xstrdup(r.port);
+			req->req = xstrdup(r.req);
 			if (load_cert(&imsg, req) == -1)
 				die();
 			if (bufio_init(&req->bio) == -1)
@@ -706,8 +703,7 @@ net_main(void)
 		exit(1);
 
 	/* Setup pipe and event handler to the main process */
-	if ((iev_ui = malloc(sizeof(*iev_ui))) == NULL)
-		die();
+	iev_ui = xmalloc(sizeof(*iev_ui));
 	imsg_init(&iev_ui->ibuf, 3);
 	iev_ui->handler = handle_dispatch_imsg;
 	iev_ui->events = EV_READ;
blob - 74be21dae9822f167e4bd8b6ee67688c1f132f01
blob + bc4375d12afe4eed30c1e7f421e93f0c50da541c
--- parse.y
+++ parse.y
@@ -37,6 +37,7 @@
 #include "keymap.h"
 #include "telescope.h"
 #include "utils.h"
+#include "xwrapper.h"
 
 typedef struct {
 	union {
@@ -318,8 +319,7 @@ eow:
 			yyerror("number is %s: %s", errstr, buf);
 		return NUMBER;
 	}
-	if ((str = strdup(buf)) == NULL)
-		err(1, "%s", __func__);
+	str = xstrdup(buf);
 	yylval.str = str;
 	return STRING;
 
@@ -453,8 +453,7 @@ attrname(const char *n)
 	int ret, found;
 	char *ap, *dup, *orig;
 
-	if ((dup = strdup(n)) == NULL)
-		err(1, "strdup");
+	dup = xstrdup(n);
 
 	orig = dup;
 
@@ -518,17 +517,14 @@ add_proxy(char *proto, char *proxy)
 		return;
 	}
 
-	if ((p = calloc(1, sizeof(*p))) == NULL)
-		err(1, "calloc");
+	p = xcalloc(1, sizeof(*p));
 
 	p->match_proto = proto;
 	p->proto = PROTO_GEMINI;
 
-	if ((p->host = strdup(iri.iri_host)) == NULL)
-		err(1, "strdup");
+	p->host = xstrdup(iri.iri_host);
 
-	if ((p->port = strdup(iri.iri_portstr)) == NULL)
-		err(1, "strdup");
+	p->port = xstrdup(iri.iri_portstr);
 
 	TAILQ_INSERT_HEAD(&proxies, p, proxies);
 }
blob - 8378bc5ceea7d3569551817640f475a78fe5933a
blob + c5a11cdd51c140436f42cccc2251130c80695868
--- parser.c
+++ parser.c
@@ -22,6 +22,7 @@
 #include "hist.h"
 #include "parser.h"
 #include "telescope.h"
+#include "xwrapper.h"
 
 static int parser_foreach_line(struct buffer *, const char *, size_t);
 
@@ -137,8 +138,7 @@ parser_append(struct buffer *b, const char *buf, size_
 	char *t;
 
 	newlen = len + b->len;
-	if ((t = calloc(1, newlen)) == NULL)
-		return 0;
+	t = xcalloc(1, newlen);
 	memcpy(t, b->buf, b->len);
 	memcpy(t + b->len, buf, len);
 	free(b->buf);
@@ -164,8 +164,7 @@ parser_set_buf(struct buffer *b, const char *buf, size
 	 * overlap!
 	 */
 
-	if ((tmp = calloc(1, len)) == NULL)
-		return 0;
+	tmp = xcalloc(1, len);
 	memcpy(tmp, buf, len);
 	free(b->buf);
 	b->buf = tmp;
blob - d4b1532f36d28b1ffe6edab81972ea9a3fbfff2e
blob + 8b325522712df1b842aa572e030a9b04e9fad200
--- parser_gemtext.c
+++ parser_gemtext.c
@@ -32,6 +32,7 @@
 #include "parser.h"
 #include "telescope.h"
 #include "utf8.h"
+#include "xwrapper.h"
 
 static int	gemtext_parse_line(struct buffer *, const char *, size_t);
 static int	gemtext_free(struct buffer *);
@@ -53,8 +54,7 @@ emit_line(struct buffer *b, enum line_type type, char 
 {
 	struct line *l;
 
-	if ((l = calloc(1, sizeof(*l))) == NULL)
-		return 0;
+	l = xcalloc(1, sizeof(*l));
 
 	l->type = type;
 	l->line = line;
@@ -110,18 +110,15 @@ parse_link(struct buffer *b, const char *line, size_t 
 	while (len > 0 && !isspace((unsigned char)line[0]))
 		line++, len--;
 
-	if ((url = strndup(start, line - start)) == NULL)
-		return 0;
+	url = xstrndup(start, line - start);
 
 	while (len > 0 && isspace(line[0]))
 		line++, len--;
 
 	if (len == 0) {
-		if ((label = strdup(url)) == NULL)
-			return 0;
+		label = xstrdup(url);
 	} else {
-		if ((label = strndup(line, len)) == NULL)
-			return 0;
+		label = xstrndup(line, len);
 	}
 
 	return emit_line(b, LINE_LINK, label, url);
@@ -150,8 +147,7 @@ parse_title(struct buffer *b, const char *line, size_t
 	if (t == LINE_TITLE_1 && *b->title == '\0')
 		strncpy(b->title, line, MIN(sizeof(b->title)-1, len));
 
-	if ((l = strndup(line, len)) == NULL)
-		return 0;
+	l = xstrndup(line, len);
 	return emit_line(b, t, l, NULL);
 }
 
@@ -168,8 +164,7 @@ gemtext_parse_line(struct buffer *b, const char *line,
 
 		if (len == 0)
 			return emit_line(b, LINE_PRE_CONTENT, NULL, NULL);
-		if ((l = strndup(line, len)) == NULL)
-			return 0;
+		l = xstrndup(line, len);
 		return emit_line(b, LINE_PRE_CONTENT, l, NULL);
 	}
 
@@ -186,8 +181,7 @@ gemtext_parse_line(struct buffer *b, const char *line,
 			line++, len--;
 		if (len == 0)
 			return emit_line(b, LINE_ITEM, NULL, NULL);
-		if ((l = strndup(line, len)) == NULL)
-			return 0;
+		l = xstrndup(line, len);
 		return emit_line(b, LINE_ITEM, l, NULL);
 
 	case '>':
@@ -196,8 +190,7 @@ gemtext_parse_line(struct buffer *b, const char *line,
 			line++, len--;
 		if (len == 0)
 			return emit_line(b, LINE_QUOTE, NULL, NULL);
-		if ((l = strndup(line, len)) == NULL)
-			return 0;
+		l = xstrndup(line, len);
 		return emit_line(b, LINE_QUOTE, l, NULL);
 
 	case '=':
@@ -219,13 +212,11 @@ gemtext_parse_line(struct buffer *b, const char *line,
 		if (len == 0)
 			return emit_line(b, LINE_PRE_START,
 			    NULL, NULL);
-		if ((l = strndup(line, len)) == NULL)
-			return 0;
+		l = xstrndup(line, len);
 		return emit_line(b, LINE_PRE_START, l, NULL);
 	}
 
-	if ((l = strndup(line, len)) == NULL)
-		return 0;
+	l = xstrndup(line, len);
 	return emit_line(b, LINE_TEXT, l, NULL);
 }
 
blob - bff31442688fddc4f4b74b0f4385ff6b72ae4139
blob + 9e499812343f69722a0ffdabbc7467a06e8512dc
--- parser_gophermap.c
+++ parser_gophermap.c
@@ -24,6 +24,7 @@
 #include "parser.h"
 #include "telescope.h"
 #include "utils.h"
+#include "xwrapper.h"
 
 #ifndef LINE_MAX
 #define LINE_MAX 2048
@@ -94,11 +95,9 @@ emit_line(struct buffer *b, enum line_type type, struc
 	struct line *l;
 	char buf[LINE_MAX];
 
-	if ((l = calloc(1, sizeof(*l))) == NULL)
-		goto err;
+	l = xcalloc(1, sizeof(*l));
 
-	if ((l->line = strdup(s->ds)) == NULL)
-		goto err;
+	l->line = xstrdup(s->ds);
 
 	switch (l->type = type) {
 	case LINE_LINK:
@@ -107,8 +106,7 @@ emit_line(struct buffer *b, enum line_type type, struc
 		} else if (selector2uri(s, buf, sizeof(buf)) == -1)
 			goto err;
 
-		if ((l->alt = strdup(buf)) == NULL)
-			goto err;
+		l->alt = xstrdup(buf);
 		break;
 
 	default:
blob - 1cedf3c9f52b03bbb663825a44462ef556f833d8
blob + 29cb6b61ad7bb608665cad2429315d84599c3cf2
--- parser_textpatch.c
+++ parser_textpatch.c
@@ -26,6 +26,7 @@
 #include "parser.h"
 #include "telescope.h"
 #include "utils.h"
+#include "xwrapper.h"
 
 static int	tpatch_emit_line(struct buffer *, const char *, size_t);
 static int	tpatch_parse_line(struct buffer *, const char *, size_t);
@@ -41,8 +42,7 @@ tpatch_emit_line(struct buffer *b, const char *line, s
 {
 	struct line *l;
 
-	if ((l = calloc(1, sizeof(*l))) == NULL)
-		return 0;
+	l = xcalloc(1, sizeof(*l));
 
 	if (b->parser_flags & PARSER_IN_PATCH_HDR)
 		l->type = LINE_PATCH_HDR;
@@ -50,10 +50,7 @@ tpatch_emit_line(struct buffer *b, const char *line, s
 		l->type = LINE_PATCH;
 
 	if (linelen != 0) {
-		if ((l->line = calloc(1, linelen+1)) == NULL) {
-			free(l);
-			return 0;
-		}
+		l->line = xcalloc(1, linelen + 1);
 
 		memcpy(l->line, line, linelen);
 
blob - 33645f01424e35748d8eb886bcfc083a71760df4
blob + 6f76ed17e48305e71f7f24617e0371b13030f468
--- parser_textplain.c
+++ parser_textplain.c
@@ -25,6 +25,7 @@
 
 #include "parser.h"
 #include "telescope.h"
+#include "xwrapper.h"
 
 static int	textplain_parse_line(struct buffer *, const char *, size_t);
 
@@ -38,16 +39,12 @@ emit_line(struct buffer *b, const char *line, size_t l
 {
 	struct line *l;
 
-	if ((l = calloc(1, sizeof(*l))) == NULL)
-		return 0;
+	l = xcalloc(1, sizeof(*l));
 
 	l->type = LINE_TEXT;
 
 	if (len != 0) {
-		if ((l->line = calloc(1, len+1)) == NULL) {
-			free(l);
-			return 0;
-		}
+		l->line = xcalloc(1, len + 1);
 
 		memcpy(l->line, line, len);
 	}
blob - bed2d3e5578f38695e8bf6c97905898e363d76b5
blob + b775862464db1d3a1f5682d5436f33f36d8a12c3
--- session.c
+++ session.c
@@ -36,6 +36,7 @@
 #include "session.h"
 #include "tofu.h"
 #include "ui.h"
+#include "xwrapper.h"
 
 struct history	history;
 
@@ -68,10 +69,7 @@ new_tab(const char *url, const char *base, struct tab 
 	ui_schedule_redraw();
 	autosave_hook();
 
-	if ((tab = calloc(1, sizeof(*tab))) == NULL) {
-		ev_break();
-		return NULL;
-	}
+	tab = xcalloc(1, sizeof(*tab));
 
 	if ((tab->hist = hist_new(HIST_LINEAR)) == NULL) {
 		free(tab);
@@ -316,8 +314,7 @@ history_push(struct histitem *hi)
 			return;
 	}
 
-	if ((uri = strdup(hi->uri)) == NULL)
-		abort();
+	uri = xstrdup(hi->uri);
 
 	/* don't grow too much; replace the oldest */
 	if (history.len == HISTORY_CAP) {
@@ -376,8 +373,7 @@ history_add(const char *uri)
 			insert = i;
 	}
 
-	if ((u = strdup(uri)) == NULL)
-		return;
+	u = xstrdup(uri);
 
 	/* if history is full, replace the oldest one */
 	if (history.len == HISTORY_CAP) {
@@ -464,10 +460,7 @@ load_certs(struct ohash *certs)
 	if ((f = fopen(known_hosts_file, "r")) == NULL)
 		return;
 
-	if ((e = calloc(1, sizeof(*e))) == NULL) {
-		fclose(f);
-		return;
-	}
+	e = xcalloc(1, sizeof(*e));
 
 	while ((linelen = getline(&line, &linesize, f)) != -1) {
 		lineno++;
blob - 317fa406cdd33452a6af50f2b4406942791fffcb
blob + 07fb73cb5c8bef4e70ffe96a09e11a7868948b53
--- telescope.c
+++ telescope.c
@@ -51,6 +51,7 @@
 #include "tofu.h"
 #include "ui.h"
 #include "utils.h"
+#include "xwrapper.h"
 
 static const struct option longopts[] = {
 	{"help",	no_argument,	NULL,	'h'},
@@ -207,8 +208,7 @@ handle_imsg_check_cert(struct imsg *imsg)
 			abort();
 
 		tofu_res = 1;	/* trust on first use */
-		if ((e = calloc(1, sizeof(*e))) == NULL)
-			abort();
+		e = xcalloc(1, sizeof(*e));
 		strlcpy(e->domain, host, sizeof(e->domain));
 		if (*port != '\0' && strcmp(port, "1965")) {
 			strlcat(e->domain, ":", sizeof(e->domain));
@@ -232,8 +232,7 @@ handle_imsg_check_cert(struct imsg *imsg)
 	} else {
 		tab->trust = TS_UNTRUSTED;
 		load_page_from_str(tab, "# Certificate mismatch\n");
-		if ((tab->cert = strdup(hash)) == NULL)
-			die();
+		tab->cert = xstrdup(hash);
 		ui_yornp("Certificate mismatch.  Proceed?",
 		    handle_check_cert_user_choice, tab);
 	}
@@ -289,8 +288,7 @@ handle_maybe_save_new_cert(int accept, struct tab *tab
 	if (!accept)
 		goto end;
 
-	if ((e = calloc(1, sizeof(*e))) == NULL)
-		die();
+	e = xcalloc(1, sizeof(*e));
 
 	strlcpy(e->domain, host, sizeof(e->domain));
 	if (*port != '\0' && strcmp(port, "1965")) {
@@ -349,9 +347,7 @@ handle_request_response(struct tab *tab)
 		load_page_from_str(tab, err_pages[tab->code]);
 	} else if (tab->code < 20) {	/* 1x */
 		free(tab->last_input_url);
-		tab->last_input_url = strdup(hist_cur(tab->hist));
-		if (tab->last_input_url == NULL)
-			die();
+		tab->last_input_url = xstrdup(hist_cur(tab->hist));
 
 		load_page_from_str(tab, err_pages[tab->code]);
 		ui_require_input(tab, tab->code == 11, ir_select_gemini);
@@ -479,9 +475,8 @@ handle_dispatch_imsg(int fd, int event, void *data)
 			if (imsg_get_ibuf(&imsg, &ibuf) == -1 ||
 			    ibuf_borrow_str(&ibuf, &str) == -1)
 				die();
-			if (asprintf(&page, "# Error loading %s\n\n> %s\n",
-			    hist_cur(tab->hist), str) == -1)
-				die();
+			xasprintf(&page, "# Error loading %s\n\n> %s\n",
+				  hist_cur(tab->hist), str);
 			load_page_from_str(tab, page);
 			free(page);
 			break;
@@ -681,9 +676,7 @@ load_gopher_url(struct tab *tab, const char *url)
 		break;
 	case '7':
 		free(tab->last_input_url);
-		tab->last_input_url = strdup(url);
-		if (tab->last_input_url == NULL)
-			die();
+		tab->last_input_url = xstrdup(url);
 		ui_require_input(tab, 0, ir_select_gopher);
 		load_page_from_str(tab, err_pages[10]);
 		return;
@@ -803,9 +796,8 @@ do_load_url(struct tab *tab, const char *url, const ch
 	tab->trust = TS_UNKNOWN;
 
 	if (iri_parse(base, url, &tab->iri) == -1) {
-		if (asprintf(&t, "# error loading %s\n>%s\n",
-		    url, "Can't parse the IRI") == -1)
-			die();
+		xasprintf(&t, "# error loading %s\n>%s\n", url,
+			  "Can't parse the IRI");
 		hist_set_cur(tab->hist, url);
 		load_page_from_str(tab, t);
 		free(t);
@@ -1153,8 +1145,7 @@ main(int argc, char * const *argv)
 	if (argc != 0) {
 		char *base;
 
-		if (asprintf(&base, "file://%s/", cwd) == -1)
-			err(1, "asprintf");
+		xasprintf(&base, "file://%s/", cwd);
 
 		has_url = 1;
 		humanify_url(argv[0], base, url, sizeof(url));
blob - 1932608bb4c189d223d4c5c234139c1ef7753214
blob + b152463261527e4d480f4ec81277b9fa66ca1c53
--- test/Makefile.am
+++ test/Makefile.am
@@ -8,7 +8,9 @@ gmparser_SOURCES =	gmparser.c				\
 			$(top_srcdir)/iri.h			\
 			$(top_srcdir)/parser.c			\
 			$(top_srcdir)/parser.h			\
-			$(top_srcdir)/parser_gophermap.c
+			$(top_srcdir)/parser_gophermap.c 	\
+			$(top_srcdir)/xwrapper.c 		\
+			$(top_srcdir)/xwrapper.h
 
 gmiparser_SOURCES =	gmiparser.c				\
 			$(top_srcdir)/compat.h			\
@@ -16,7 +18,9 @@ gmiparser_SOURCES =	gmiparser.c				\
 			$(top_srcdir)/hist.h			\
 			$(top_srcdir)/parser.c			\
 			$(top_srcdir)/parser.h			\
-			$(top_srcdir)/parser_gemtext.c
+			$(top_srcdir)/parser_gemtext.c 		\
+			$(top_srcdir)/xwrapper.c 		\
+			$(top_srcdir)/xwrapper.h
 
 iritest_SOURCES =	iritest.c				\
 			$(top_srcdir)/iri.c			\
@@ -24,13 +28,17 @@ iritest_SOURCES =	iritest.c				\
 
 evtest_SOURCES =	evtest.c				\
 			$(top_srcdir)/ev.c			\
-			$(top_srcdir)/ev.h
+			$(top_srcdir)/ev.h			\
+			$(top_srcdir)/xwrapper.c 		\
+			$(top_srcdir)/xwrapper.h
 
 mailcap_SOURCES =	$(top_srcdir)/test/mailcap.c		\
 			$(top_srcdir)/mailcap.c			\
-			$(top_srcdir)/mailcap.h
+			$(top_srcdir)/mailcap.h			\
+			$(top_srcdir)/xwrapper.c 		\
+			$(top_srcdir)/xwrapper.h
 
-AM_CFLAGS =		-I$(top_srcdir)
+AM_CFLAGS =		-I$(top_srcdir) -I$(top_srcdir)/compat
 
 LDADD =			$(LIBOBJS)
 
blob - ad8310d2c5dcc0005a0e4a875299a7f07bc15d1a
blob + b71e434660f40cedf450a966815e949f53fb72f7
--- tofu.c
+++ tofu.c
@@ -25,6 +25,7 @@
 #include "fs.h"
 #include "tofu.h"
 #include "utils.h"
+#include "xwrapper.h"
 
 void
 tofu_init(struct ohash *h, unsigned int sz, ptrdiff_t ko)
@@ -150,8 +151,7 @@ tofu_temp_trust(struct ohash *h, const char *host, con
 {
 	struct tofu_entry *e;
 
-	if ((e = calloc(1, sizeof(*e))) == NULL)
-		abort();
+	e = xcalloc(1, sizeof(*e));
 
 	strlcpy(e->domain, host, sizeof(e->domain));
 	if (*port != '\0' && strcmp(port, "1965")) {
blob - 685c24e17b0846399656bb4517e1d93661093793
blob + 1ffdac26c249c206bbc450fd8168e412a92dbbf6
--- utils.c
+++ utils.c
@@ -22,6 +22,7 @@
 #include <string.h>
 
 #include "utils.h"
+#include "xwrapper.h"
 
 int
 mark_nonblock_cloexec(int fd)
@@ -54,16 +55,14 @@ has_suffix(const char *str, const char *sufx)
 void *
 hash_alloc(size_t len, void *d)
 {
-	if ((d = malloc(len)) == NULL)
-		abort();
+	d = xmalloc(len);
 	return d;
 }
 
 void *
 hash_calloc(size_t nmemb, size_t size, void *d)
 {
-	if ((d = calloc(nmemb, size)) == NULL)
-		abort();
+	d = xcalloc(nmemb, size);
 	return d;
 }
 
blob - 2a58e03514ae257ca15008d70eedece728b428c0
blob + 3054f79000e3cbe7f8e905d1994cc436fccd7cf4
--- wrap.c
+++ wrap.c
@@ -26,6 +26,7 @@
 #include "defaults.h"
 #include "telescope.h"
 #include "utf8.h"
+#include "xwrapper.h"
 
 void
 erase_buffer(struct buffer *buffer)
@@ -85,8 +86,7 @@ push_line(struct buffer *buffer, struct line *l, const
 	if (!(l->flags & L_HIDDEN))
 		buffer->line_max++;
 
-	if ((vl = calloc(1, sizeof(*vl))) == NULL)
-		return 0;
+	vl = xcalloc(1, sizeof(*vl));
 
 	vl->parent = l;
 	if (len != 0) {
blob - /dev/null
blob + 51a7e30021e353b87011b86e71a3398ba378818f (mode 644)
--- /dev/null
+++ xwrapper.c
@@ -0,0 +1,163 @@
+/* $OpenBSD$ */
+
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ * Versions of malloc and friends that check their results, and never return
+ * failure (they call errx if they encounter an error).
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ */
+
+#include "compat.h"
+
+#include <errno.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "xwrapper.h"
+
+void *
+xmalloc(size_t size)
+{
+	void *ptr;
+
+	if (size == 0)
+		errx(1, "xmalloc: zero size");
+	ptr = malloc(size);
+	if (ptr == NULL)
+		errx(1, "xmalloc: allocating %zu bytes: %s",
+		    size, strerror(errno));
+	return ptr;
+}
+
+void *
+xcalloc(size_t nmemb, size_t size)
+{
+	void *ptr;
+
+	if (size == 0 || nmemb == 0)
+		errx(1, "xcalloc: zero size");
+	ptr = calloc(nmemb, size);
+	if (ptr == NULL)
+		errx(1, "xcalloc: allocating %zu * %zu bytes: %s",
+		    nmemb, size, strerror(errno));
+	return ptr;
+}
+
+void *
+xrealloc(void *ptr, size_t size)
+{
+	return xreallocarray(ptr, 1, size);
+}
+
+void *
+xreallocarray(void *ptr, size_t nmemb, size_t size)
+{
+	void *new_ptr;
+
+	if (nmemb == 0 || size == 0)
+		errx(1, "xreallocarray: zero size");
+	new_ptr = reallocarray(ptr, nmemb, size);
+	if (new_ptr == NULL)
+		errx(1, "xreallocarray: allocating %zu * %zu bytes: %s",
+		    nmemb, size, strerror(errno));
+	return new_ptr;
+}
+
+void *
+xrecallocarray(void *ptr, size_t oldnmemb, size_t nmemb, size_t size)
+{
+	void *new_ptr;
+
+	if (nmemb == 0 || size == 0)
+		errx(1, "xrecallocarray: zero size");
+	new_ptr = recallocarray(ptr, oldnmemb, nmemb, size);
+	if (new_ptr == NULL)
+		errx(1, "xrecallocarray: allocating %zu * %zu bytes: %s",
+		    nmemb, size, strerror(errno));
+	return new_ptr;
+}
+
+char *
+xstrdup(const char *str)
+{
+	char *cp;
+
+	if ((cp = strdup(str)) == NULL)
+		errx(1, "xstrdup: %s", strerror(errno));
+	return cp;
+}
+
+char *
+xstrndup(const char *str, size_t maxlen)
+{
+	char *cp;
+
+	if ((cp = strndup(str, maxlen)) == NULL)
+		errx(1, "xstrndup: %s", strerror(errno));
+	return cp;
+}
+
+int
+xasprintf(char **ret, const char *fmt, ...)
+{
+	va_list ap;
+	int i;
+
+	va_start(ap, fmt);
+	i = xvasprintf(ret, fmt, ap);
+	va_end(ap);
+
+	return i;
+}
+
+int
+xvasprintf(char **ret, const char *fmt, va_list ap)
+{
+	int i;
+
+	i = vasprintf(ret, fmt, ap);
+
+	if (i == -1)
+		errx(1, "xasprintf: %s", strerror(errno));
+
+	return i;
+}
+
+int
+xsnprintf(char *str, size_t len, const char *fmt, ...)
+{
+	va_list ap;
+	int i;
+
+	va_start(ap, fmt);
+	i = xvsnprintf(str, len, fmt, ap);
+	va_end(ap);
+
+	return i;
+}
+
+int
+xvsnprintf(char *str, size_t len, const char *fmt, va_list ap)
+{
+	int i;
+
+	if (len > INT_MAX)
+		errx(1, "xsnprintf: len > INT_MAX");
+
+	i = vsnprintf(str, len, fmt, ap);
+
+	if (i < 0 || i >= (int)len)
+		errx(1, "xsnprintf: overflow");
+
+	return i;
+}
blob - /dev/null
blob + 49ddac115ac2df9d4e7ea4aaf1443fc0a082f393 (mode 644)
--- /dev/null
+++ xwrapper.h
@@ -0,0 +1,48 @@
+/* $OpenBSD$ */
+
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ * Created: Mon Mar 20 22:09:17 1995 ylo
+ *
+ * Versions of malloc and friends that check their results, and never return
+ * failure (they call fatal if they encounter an error).
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ */
+
+#ifndef XWRAPPER_H
+#define XWRAPPER_H
+
+#if !defined(__bounded__)
+#define __bounded__(x, y, z)
+#endif
+
+void	*xmalloc(size_t);
+void	*xcalloc(size_t, size_t);
+void	*xrealloc(void *, size_t);
+void	*xreallocarray(void *, size_t, size_t);
+void	*xrecallocarray(void *, size_t, size_t, size_t);
+char	*xstrdup(const char *);
+char	*xstrndup(const char *, size_t);
+int	 xasprintf(char **, const char *, ...)
+		__attribute__((__format__ (printf, 2, 3)))
+		__attribute__((__nonnull__ (2)));
+int	 xvasprintf(char **, const char *, va_list)
+		__attribute__((__format__ (printf, 2, 0)))
+		__attribute__((__nonnull__ (2)));
+int	 xsnprintf(char *, size_t, const char *, ...)
+		__attribute__((__format__ (printf, 3, 4)))
+		__attribute__((__nonnull__ (3)))
+		__attribute__((__bounded__ (__string__, 1, 2)));
+int	 xvsnprintf(char *, size_t, const char *, va_list)
+		__attribute__((__format__ (printf, 3, 0)))
+		__attribute__((__nonnull__ (3)))
+		__attribute__((__bounded__ (__string__, 1, 2)));
+
+#endif	/* XWRAPPER_H */