cgit

commit ed5bd30ebe6921dd22948a3f33a314283f043606

Author: John Keeping <john@keeping.me.uk>

Convert cgit_print_error to a variadic function

This removes many uses of "fmt" which uses a fixed size static pool of
fixed size buffers.  Instead of relying on these, we now pass around
argument lists for as long as possible before using a strbuf to render
content of an arbitrary size.

Signed-off-by: John Keeping <john@keeping.me.uk>

 cgit.c | 18 ++++++++----------
 ui-blob.c | 8 ++++----
 ui-commit.c | 4 ++--
 ui-diff.c | 8 ++++----
 ui-patch.c | 4 ++--
 ui-shared.c | 15 +++++++++++++--
 ui-shared.h | 5 ++++-
 ui-snapshot.c | 16 ++++++++++------
 ui-stats.c | 5 ++---
 ui-tag.c | 6 +++---
 ui-tree.c | 13 +++++--------


diff --git a/cgit.c b/cgit.c
index 6f75db14a5c64e0d1684edaf876dd61667938c0b..4e512838d480e5640e3a9758bf6a764471c46349 100644
--- a/cgit.c
+++ b/cgit.c
@@ -459,7 +459,6 @@ }
 
 static int prepare_repo_cmd(struct cgit_context *ctx)
 {
-	char *tmp;
 	unsigned char sha1[20];
 	int nongit = 0;
 	int rc;
@@ -467,17 +466,16 @@
 	setenv("GIT_DIR", ctx->repo->path, 1);
 	setup_git_directory_gently(&nongit);
 	if (nongit) {
+		const char *name = ctx->repo->name;
 		rc = errno;
 		ctx->page.title = fmt("%s - %s", ctx->cfg.root_title,
 				      "config error");
-		tmp = fmt("Failed to open %s: %s",
-			  ctx->repo->name,
-			  rc ? strerror(rc) : "Not a valid git repository");
 		ctx->repo = NULL;
 		cgit_print_http_headers(ctx);
 		cgit_print_docstart(ctx);
 		cgit_print_pageheader(ctx);
-		cgit_print_error(tmp);
+		cgit_print_error("Failed to open %s: %s", name,
+				 rc ? strerror(rc) : "Not a valid git repository");
 		cgit_print_docend();
 		return 1;
 	}
@@ -501,14 +499,14 @@ 		return 1;
 	}
 
 	if (get_sha1(ctx->qry.head, sha1)) {
-		tmp = xstrdup(ctx->qry.head);
+		char *tmp = xstrdup(ctx->qry.head);
 		ctx->qry.head = ctx->repo->defbranch;
 		ctx->page.status = 404;
 		ctx->page.statusmsg = "Not found";
 		cgit_print_http_headers(ctx);
 		cgit_print_docstart(ctx);
 		cgit_print_pageheader(ctx);
-		cgit_print_error(fmt("Invalid branch: %s", tmp));
+		cgit_print_error("Invalid branch: %s", tmp);
 		cgit_print_docend();
 		return 1;
 	}
@@ -550,7 +548,7 @@ 	if (cmd->want_repo && !ctx->repo) {
 		cgit_print_http_headers(ctx);
 		cgit_print_docstart(ctx);
 		cgit_print_pageheader(ctx);
-		cgit_print_error(fmt("No repository selected"));
+		cgit_print_error("No repository selected");
 		cgit_print_docend();
 		return;
 	}
@@ -862,7 +860,7 @@ 		ctx.cfg.cache_size = 0;
 	err = cache_process(ctx.cfg.cache_size, ctx.cfg.cache_root,
 			    ctx.qry.raw, ttl, process_request, &ctx);
 	if (err)
-		cgit_print_error(fmt("Error processing page: %s (%d)",
-				     strerror(err), err));
+		cgit_print_error("Error processing page: %s (%d)",
+				 strerror(err), err);
 	return err;
 }




diff --git a/ui-blob.c b/ui-blob.c
index 1da43c81519927f99b7f67a8c08d7df0eee34359..8f6989f320b2317857b7161865aba55db915567b 100644
--- a/ui-blob.c
+++ b/ui-blob.c
@@ -94,12 +94,12 @@ 	};
 
 	if (hex) {
 		if (get_sha1_hex(hex, sha1)) {
-			cgit_print_error(fmt("Bad hex value: %s", hex));
+			cgit_print_error("Bad hex value: %s", hex);
 			return;
 		}
 	} else {
 		if (get_sha1(head, sha1)) {
-			cgit_print_error(fmt("Bad ref: %s", head));
+			cgit_print_error("Bad ref: %s", head);
 			return;
 		}
 	}
@@ -113,13 +113,13 @@ 		type = sha1_object_info(sha1,&size);
 	}
 
 	if (type == OBJ_BAD) {
-		cgit_print_error(fmt("Bad object name: %s", hex));
+		cgit_print_error("Bad object name: %s", hex);
 		return;
 	}
 
 	buf = read_sha1_file(sha1, &type, &size);
 	if (!buf) {
-		cgit_print_error(fmt("Error reading object %s", hex));
+		cgit_print_error("Error reading object %s", hex);
 		return;
 	}
 




diff --git a/ui-commit.c b/ui-commit.c
index 8310ce6667ae288baeed9a1ca201367395ada705..6b41017a1cfc4d22b916abea56fbc37376e3e553 100644
--- a/ui-commit.c
+++ b/ui-commit.c
@@ -27,12 +27,12 @@ 	if (!hex)
 		hex = ctx.qry.head;
 
 	if (get_sha1(hex, sha1)) {
-		cgit_print_error(fmt("Bad object id: %s", hex));
+		cgit_print_error("Bad object id: %s", hex);
 		return;
 	}
 	commit = lookup_commit_reference(sha1);
 	if (!commit) {
-		cgit_print_error(fmt("Bad commit reference: %s", hex));
+		cgit_print_error("Bad commit reference: %s", hex);
 		return;
 	}
 	info = cgit_parse_commit(commit);




diff --git a/ui-diff.c b/ui-diff.c
index 11155185f831b20a09de3224f61ddde3bf959119..8b38209a82e12dff0f89e62484dd8a2b84e4d83a 100644
--- a/ui-diff.c
+++ b/ui-diff.c
@@ -369,12 +369,12 @@ 		new_rev = ctx.qry.head;
 	get_sha1(new_rev, new_rev_sha1);
 	type = sha1_object_info(new_rev_sha1, &size);
 	if (type == OBJ_BAD) {
-		cgit_print_error(fmt("Bad object name: %s", new_rev));
+		cgit_print_error("Bad object name: %s", new_rev);
 		return;
 	}
 	commit = lookup_commit_reference(new_rev_sha1);
 	if (!commit || parse_commit(commit)) {
-		cgit_print_error(fmt("Bad commit: %s", sha1_to_hex(new_rev_sha1)));
+		cgit_print_error("Bad commit: %s", sha1_to_hex(new_rev_sha1));
 		return;
 	}
 
@@ -388,12 +388,12 @@
 	if (!is_null_sha1(old_rev_sha1)) {
 		type = sha1_object_info(old_rev_sha1, &size);
 		if (type == OBJ_BAD) {
-			cgit_print_error(fmt("Bad object name: %s", sha1_to_hex(old_rev_sha1)));
+			cgit_print_error("Bad object name: %s", sha1_to_hex(old_rev_sha1));
 			return;
 		}
 		commit2 = lookup_commit_reference(old_rev_sha1);
 		if (!commit2 || parse_commit(commit2)) {
-			cgit_print_error(fmt("Bad commit: %s", sha1_to_hex(old_rev_sha1)));
+			cgit_print_error("Bad commit: %s", sha1_to_hex(old_rev_sha1));
 			return;
 		}
 	}




diff --git a/ui-patch.c b/ui-patch.c
index 66def3c9075f9379b4830eeb9109b05d70d31db2..fbb92cc4eca31de7cf9d998c3cec46a0e1937ccb 100644
--- a/ui-patch.c
+++ b/ui-patch.c
@@ -94,12 +94,12 @@ 	if (!hex)
 		hex = ctx.qry.head;
 
 	if (get_sha1(hex, sha1)) {
-		cgit_print_error(fmt("Bad object id: %s", hex));
+		cgit_print_error("Bad object id: %s", hex);
 		return;
 	}
 	commit = lookup_commit_reference(sha1);
 	if (!commit) {
-		cgit_print_error(fmt("Bad commit reference: %s", hex));
+		cgit_print_error("Bad commit reference: %s", hex);
 		return;
 	}
 	info = cgit_parse_commit(commit);




diff --git a/ui-shared.c b/ui-shared.c
index c1f3c202c90592d49874c46a8b6a2a3da9c749be..b93b77aee4f5718ad74e36a3bc3d4d3a3ed9f65e 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -28,10 +28,21 @@ 		   tm->tm_mday, month[tm->tm_mon], 1900 + tm->tm_year,
 		   tm->tm_hour, tm->tm_min, tm->tm_sec);
 }
 
-void cgit_print_error(const char *msg)
+void cgit_print_error(const char *fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	cgit_vprint_error(fmt, ap);
+	va_end(ap);
+}
+
+void cgit_vprint_error(const char *fmt, va_list ap)
 {
+	va_list cp;
 	html("<div class='error'>");
-	html_txt(msg);
+	va_copy(cp, ap);
+	html_vtxtf(fmt, cp);
+	va_end(cp);
 	html("</div>\n");
 }
 




diff --git a/ui-shared.h b/ui-shared.h
index 5f8b6295937dfc24a201c556897a71364f7db3d3..5987e77cafb2cfce3f589a7c89ab3c425152a0f4 100644
--- a/ui-shared.h
+++ b/ui-shared.h
@@ -52,7 +52,10 @@
 extern void cgit_submodule_link(const char *class, char *path,
 				const char *rev);
 
-extern void cgit_print_error(const char *msg);
+__attribute__((format (printf,1,2)))
+extern void cgit_print_error(const char *fmt, ...);
+__attribute__((format (printf,1,0)))
+extern void cgit_vprint_error(const char *fmt, va_list ap);
 extern void cgit_print_date(time_t secs, const char *format, int local_time);
 extern void cgit_print_age(time_t t, time_t max_relative, const char *format);
 extern void cgit_print_http_headers(struct cgit_context *ctx);




diff --git a/ui-snapshot.c b/ui-snapshot.c
index 9be5dbef808526b3b0dd9d518163b206ead37b9f..a47884e85556ff75d24364f67f441994d339ca7b 100644
--- a/ui-snapshot.c
+++ b/ui-snapshot.c
@@ -100,11 +100,11 @@ {
 	unsigned char sha1[20];
 
 	if (get_sha1(hex, sha1)) {
-		cgit_print_error(fmt("Bad object id: %s", hex));
+		cgit_print_error("Bad object id: %s", hex);
 		return 1;
 	}
 	if (!lookup_commit_reference(sha1)) {
-		cgit_print_error(fmt("Not a commit reference: %s", hex));
+		cgit_print_error("Not a commit reference: %s", hex);
 		return 1;
 	}
 	ctx.page.mimetype = xstrdup(format->mimetype);
@@ -154,13 +154,18 @@
 	return NULL;
 }
 
-static void show_error(char *msg)
+__attribute__((format (printf, 1, 2)))
+static void show_error(char *fmt, ...)
 {
+	va_list ap;
+
 	ctx.page.mimetype = "text/html";
 	cgit_print_http_headers(&ctx);
 	cgit_print_docstart(&ctx);
 	cgit_print_pageheader(&ctx);
-	cgit_print_error(msg);
+	va_start(ap, fmt);
+	cgit_vprint_error(fmt, ap);
+	va_end(ap);
 	cgit_print_docend();
 }
 
@@ -177,8 +182,7 @@ 	}
 
 	f = get_format(filename);
 	if (!f) {
-		show_error(xstrdup(fmt("Unsupported snapshot format: %s",
-				       filename)));
+		show_error("Unsupported snapshot format: %s", filename);
 		return;
 	}
 




diff --git a/ui-stats.c b/ui-stats.c
index 52e9b91bba6a4a3c4a6ca3c1f59925ead5863da7..28b794fd3a1354dd0175047e696a0cd7ca11ad39 100644
--- a/ui-stats.c
+++ b/ui-stats.c
@@ -374,12 +374,11 @@ 		code = ctx->qry.period;
 
 	i = cgit_find_stats_period(code, &period);
 	if (!i) {
-		cgit_print_error(fmt("Unknown statistics type: %c", code[0]));
+		cgit_print_error("Unknown statistics type: %c", code[0]);
 		return;
 	}
 	if (i > ctx->repo->max_stats) {
-		cgit_print_error(fmt("Statistics type disabled: %s",
-				     period->name));
+		cgit_print_error("Statistics type disabled: %s", period->name);
 		return;
 	}
 	authors = collect_stats(ctx, period);




diff --git a/ui-tag.c b/ui-tag.c
index 5a22696a0b159accd0e239ee8bab2c8c72debb28..397e15b83638531eae7adf931f043c18b5032a76 100644
--- a/ui-tag.c
+++ b/ui-tag.c
@@ -50,18 +50,18 @@ 	if (!revname)
 		revname = ctx.qry.head;
 
 	if (get_sha1(fmt("refs/tags/%s", revname), sha1)) {
-		cgit_print_error(fmt("Bad tag reference: %s", revname));
+		cgit_print_error("Bad tag reference: %s", revname);
 		return;
 	}
 	obj = parse_object(sha1);
 	if (!obj) {
-		cgit_print_error(fmt("Bad object id: %s", sha1_to_hex(sha1)));
+		cgit_print_error("Bad object id: %s", sha1_to_hex(sha1));
 		return;
 	}
 	if (obj->type == OBJ_TAG) {
 		tag = lookup_tag(sha1);
 		if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag))) {
-			cgit_print_error(fmt("Bad tag object: %s", revname));
+			cgit_print_error("Bad tag object: %s", revname);
 			return;
 		}
 		html("<table class='commit-info'>\n");




diff --git a/ui-tree.c b/ui-tree.c
index d7135532baf8c6f69da6fe2b5c01599f75b351ee..aebe145cb88585ff2c05f4f3f915c47f7a914ae1 100644
--- a/ui-tree.c
+++ b/ui-tree.c
@@ -95,15 +95,13 @@ 	unsigned long size;
 
 	type = sha1_object_info(sha1, &size);
 	if (type == OBJ_BAD) {
-		cgit_print_error(fmt("Bad object name: %s",
-				     sha1_to_hex(sha1)));
+		cgit_print_error("Bad object name: %s", sha1_to_hex(sha1));
 		return;
 	}
 
 	buf = read_sha1_file(sha1, &type, &size);
 	if (!buf) {
-		cgit_print_error(fmt("Error reading object %s",
-				     sha1_to_hex(sha1)));
+		cgit_print_error("Error reading object %s", sha1_to_hex(sha1));
 		return;
 	}
 
@@ -209,8 +207,7 @@ 	};
 
 	tree = parse_tree_indirect(sha1);
 	if (!tree) {
-		cgit_print_error(fmt("Not a tree object: %s",
-				     sha1_to_hex(sha1)));
+		cgit_print_error("Not a tree object: %s", sha1_to_hex(sha1));
 		return;
 	}
 
@@ -273,12 +270,12 @@ 	if (!rev)
 		rev = ctx.qry.head;
 
 	if (get_sha1(rev, sha1)) {
-		cgit_print_error(fmt("Invalid revision name: %s", rev));
+		cgit_print_error("Invalid revision name: %s", rev);
 		return;
 	}
 	commit = lookup_commit_reference(sha1);
 	if (!commit || parse_commit(commit)) {
-		cgit_print_error(fmt("Invalid commit reference: %s", rev));
+		cgit_print_error("Invalid commit reference: %s", rev);
 		return;
 	}