summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul-Sebastian Ungureanu <ungureanupaulsebastian@gmail.com>2019-02-25 23:16:07 (GMT)
committerJunio C Hamano <gitster@pobox.com>2019-02-28 23:03:46 (GMT)
commit5ef264dbdbc48b44ad5fc37e7542f3dc70e3e8c5 (patch)
tree7cdcd347f866864ddd78f5faac397751624e04f3
parente71c4a88f65ca1d325f52b19bf79c3660eab50f7 (diff)
downloadgit-5ef264dbdbc48b44ad5fc37e7542f3dc70e3e8c5.zip
git-5ef264dbdbc48b44ad5fc37e7542f3dc70e3e8c5.tar.gz
git-5ef264dbdbc48b44ad5fc37e7542f3dc70e3e8c5.tar.bz2
strbuf.c: add `strbuf_insertf()` and `strbuf_vinsertf()`
Implement `strbuf_insertf()` and `strbuf_vinsertf()` to insert data using a printf format string. Original-idea-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Paul-Sebastian Ungureanu <ungureanupaulsebastian@gmail.com> Helped-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--strbuf.c36
-rw-r--r--strbuf.h9
2 files changed, 45 insertions, 0 deletions
diff --git a/strbuf.c b/strbuf.c
index 82e90f1..87ecf7f 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -249,6 +249,42 @@ void strbuf_insert(struct strbuf *sb, size_t pos, const void *data, size_t len)
strbuf_splice(sb, pos, 0, data, len);
}
+void strbuf_vinsertf(struct strbuf *sb, size_t pos, const char *fmt, va_list ap)
+{
+ int len, len2;
+ char save;
+ va_list cp;
+
+ if (pos > sb->len)
+ die("`pos' is too far after the end of the buffer");
+ va_copy(cp, ap);
+ len = vsnprintf(sb->buf + sb->len, 0, fmt, cp);
+ va_end(cp);
+ if (len < 0)
+ BUG("your vsnprintf is broken (returned %d)", len);
+ if (!len)
+ return; /* nothing to do */
+ if (unsigned_add_overflows(sb->len, len))
+ die("you want to use way too much memory");
+ strbuf_grow(sb, len);
+ memmove(sb->buf + pos + len, sb->buf + pos, sb->len - pos);
+ /* vsnprintf() will append a NUL, overwriting one of our characters */
+ save = sb->buf[pos + len];
+ len2 = vsnprintf(sb->buf + pos, len + 1, fmt, ap);
+ sb->buf[pos + len] = save;
+ if (len2 != len)
+ BUG("your vsnprintf is broken (returns inconsistent lengths)");
+ strbuf_setlen(sb, sb->len + len);
+}
+
+void strbuf_insertf(struct strbuf *sb, size_t pos, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ strbuf_vinsertf(sb, pos, fmt, ap);
+ va_end(ap);
+}
+
void strbuf_remove(struct strbuf *sb, size_t pos, size_t len)
{
strbuf_splice(sb, pos, len, "", 0);
diff --git a/strbuf.h b/strbuf.h
index be02150..8f8fe01 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -245,6 +245,15 @@ void strbuf_addchars(struct strbuf *sb, int c, size_t n);
void strbuf_insert(struct strbuf *sb, size_t pos, const void *, size_t);
/**
+ * Insert data to the given position of the buffer giving a printf format
+ * string. The contents will be shifted, not overwritten.
+ */
+void strbuf_vinsertf(struct strbuf *sb, size_t pos, const char *fmt,
+ va_list ap);
+
+void strbuf_insertf(struct strbuf *sb, size_t pos, const char *fmt, ...);
+
+/**
* Remove given amount of data from a given position of the buffer.
*/
void strbuf_remove(struct strbuf *sb, size_t pos, size_t len);