Subject: [PATCH 01/14] strbuf: introduce strbuf_prefixf()

From: Jonathan Nieder <[email-masked]>
Date: Tue, 2 Dec 2014 21:10:16 -0800

When preparing an error message in a strbuf, it can be convenient
to add a formatted string to the beginning:

	if (transaction_commit(&t, err)) {
		strbuf_prefixf(err, "cannot fetch '%s': ", remotename);
		return -1;
	}

The new strbuf_prefixf is like strbuf_addf, except it writes its
result to the beginning of a strbuf instead of the end.

The current implementation uses strlen(strfmt(fmt, ...)) extra bytes
at the end of the strbuf as temporary scratch space for convenience
and simplicity.  A later patch can optimize if needed.

Signed-off-by: Jonathan Nieder <[email-masked]>
---
 strbuf.c | 16 ++++++++++++++++
 strbuf.h |  4 ++++
 2 files changed, 20 insertions(+)

diff --git a/strbuf.c b/strbuf.c
index 0346e74..3f4aaa3 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -219,6 +219,22 @@ void strbuf_addf(struct strbuf *sb, const char *fmt, ...)
 	va_end(ap);
 }
 
+void strbuf_prefixf(struct strbuf *sb, const char *fmt, ...)
+{
+	va_list ap;
+	size_t pos, len;
+
+	pos = sb->len;
+
+	va_start(ap, fmt);
+	strbuf_vaddf(sb, fmt, ap);
+	va_end(ap);
+
+	len = sb->len - pos;
+	strbuf_insert(sb, 0, sb->buf + pos, len);
+	strbuf_remove(sb, pos + len, len);
+}
+
 static void add_lines(struct strbuf *out,
 			const char *prefix1,
 			const char *prefix2,
diff --git a/strbuf.h b/strbuf.h
index 652b6c4..5dae48e 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -158,6 +158,10 @@ extern void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap);
 
 extern void strbuf_add_lines(struct strbuf *sb, const char *prefix, const char *buf, size_t size);
 
+/* Like strbuf_addf but insert at the front of sb instead of appending. */
+__attribute__((format (printf,2,3)))
+extern void strbuf_prefixf(struct strbuf *sb, const char *fmt, ...);
+
 /*
  * Append s to sb, with the characters '<', '>', '&' and '"' converted
  * into XML entities.