#endif
;
+/* Add sprintf-style formatted data to BUF, with a va_list. The value of ap is
+ * undefined after the call. */
+void k5_buf_add_vfmt(struct k5buf *buf, const char *fmt, va_list ap)
+#if !defined(__cplusplus) && (__GNUC__ > 2)
+ __attribute__((__format__(__printf__, 2, 0)))
+#endif
+ ;
+
/* Extend the length of buf by len and return a pointer to the reserved space,
* to be filled in by the caller. Return NULL on error. */
void *k5_buf_get_space(struct k5buf *buf, size_t len);
}
void
-k5_buf_add_fmt(struct k5buf *buf, const char *fmt, ...)
+k5_buf_add_vfmt(struct k5buf *buf, const char *fmt, va_list ap)
{
- va_list ap;
+ va_list apcopy;
int r;
size_t remaining;
char *tmp;
if (buf->buftype == K5BUF_FIXED) {
/* Format the data directly into the fixed buffer. */
- va_start(ap, fmt);
r = vsnprintf(endptr(buf), remaining, fmt, ap);
- va_end(ap);
if (SNPRINTF_OVERFLOW(r, remaining))
set_error(buf);
else
/* Optimistically format the data directly into the dynamic buffer. */
assert(buf->buftype == K5BUF_DYNAMIC);
- va_start(ap, fmt);
- r = vsnprintf(endptr(buf), remaining, fmt, ap);
- va_end(ap);
+ va_copy(apcopy, ap);
+ r = vsnprintf(endptr(buf), remaining, fmt, apcopy);
+ va_end(apcopy);
if (!SNPRINTF_OVERFLOW(r, remaining)) {
buf->len += (unsigned int) r;
return;
if (!ensure_space(buf, r))
return;
remaining = buf->space - buf->len;
- va_start(ap, fmt);
r = vsnprintf(endptr(buf), remaining, fmt, ap);
- va_end(ap);
if (SNPRINTF_OVERFLOW(r, remaining)) /* Shouldn't ever happen. */
k5_buf_free(buf);
else
/* It's a pre-C99 snprintf implementation, or something else went wrong.
* Fall back to asprintf. */
- va_start(ap, fmt);
r = vasprintf(&tmp, fmt, ap);
- va_end(ap);
if (r < 0) {
k5_buf_free(buf);
return;
free(tmp);
}
+void
+k5_buf_add_fmt(struct k5buf *buf, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ k5_buf_add_vfmt(buf, fmt, ap);
+ va_end(ap);
+}
+
void *
k5_buf_get_space(struct k5buf *buf, size_t len)
{