| 266 | } |
| 267 | |
| 268 | void strbuf_vinsertf(struct strbuf *sb, size_t pos, const char *fmt, va_list ap) |
| 269 | { |
| 270 | int len, len2; |
| 271 | char save; |
| 272 | va_list cp; |
| 273 | |
| 274 | if (pos > sb->len) |
| 275 | die("`pos' is too far after the end of the buffer"); |
| 276 | va_copy(cp, ap); |
| 277 | len = vsnprintf(sb->buf + sb->len, 0, fmt, cp); |
| 278 | va_end(cp); |
| 279 | if (len < 0) |
| 280 | die(_("unable to format message: %s"), fmt); |
| 281 | if (!len) |
| 282 | return; /* nothing to do */ |
| 283 | if (unsigned_add_overflows(sb->len, len)) |
| 284 | die("you want to use way too much memory"); |
| 285 | strbuf_grow(sb, len); |
| 286 | memmove(sb->buf + pos + len, sb->buf + pos, sb->len - pos); |
| 287 | /* vsnprintf() will append a NUL, overwriting one of our characters */ |
| 288 | save = sb->buf[pos + len]; |
| 289 | len2 = vsnprintf(sb->buf + pos, len + 1, fmt, ap); |
| 290 | sb->buf[pos + len] = save; |
| 291 | if (len2 != len) |
| 292 | BUG("your vsnprintf is broken (returns inconsistent lengths)"); |
| 293 | strbuf_setlen(sb, sb->len + len); |
| 294 | } |
| 295 | |
| 296 | void strbuf_insertf(struct strbuf *sb, size_t pos, const char *fmt, ...) |
| 297 | { |
no test coverage detected