diff options
author | Paul-Sebastian Ungureanu <ungureanupaulsebastian@gmail.com> | 2019-02-25 23:16:07 +0000 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2019-03-01 08:03:46 +0900 |
commit | 5ef264dbdbc48b44ad5fc37e7542f3dc70e3e8c5 (patch) | |
tree | 7cdcd347f866864ddd78f5faac397751624e04f3 /strbuf.c | |
parent | strbuf.c: add `strbuf_join_argv()` (diff) | |
download | tgif-5ef264dbdbc48b44ad5fc37e7542f3dc70e3e8c5.tar.xz |
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>
Diffstat (limited to 'strbuf.c')
-rw-r--r-- | strbuf.c | 36 |
1 files changed, 36 insertions, 0 deletions
@@ -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); |