autobuf: simplify abuf_vappendf
authorFerry Huberts <ferry.huberts@pelagic.nl>
Sat, 16 Apr 2016 19:18:16 +0000 (21:18 +0200)
committerFerry Huberts <ferry.huberts@pelagic.nl>
Sat, 16 Apr 2016 20:29:20 +0000 (22:29 +0200)
Signed-off-by: Ferry Huberts <ferry.huberts@pelagic.nl>
src/common/autobuf.c

index 6ecd5e3..6c11df5 100644 (file)
@@ -131,23 +131,40 @@ int
 abuf_vappendf(struct autobuf *autobuf, const char *format, va_list ap)
 {
   int rc;
-  int min_size;
   va_list ap2;
+  char *start = &autobuf->buf[autobuf->len];
+  int size_remaining = autobuf->size - autobuf->len;
+
   va_copy(ap2, ap);
-  rc = vsnprintf(autobuf->buf + autobuf->len, autobuf->size - autobuf->len, format, ap);
+
+  rc = vsnprintf(start, size_remaining, format, ap);
   va_end(ap);
-  min_size = autobuf->len + rc;
-  if (min_size >= autobuf->size) {
-    if (autobuf_enlarge(autobuf, min_size) < 0) {
-      autobuf->buf[autobuf->len] = '\0';
-      va_end(ap2);
-      return -1;
+  if (rc < 0) {
+    goto error_out;
+  }
+
+  if (rc >= size_remaining) {
+    /* output was truncated */
+
+    if (autobuf_enlarge(autobuf, autobuf->len + rc) < 0) {
+      goto error_out;
+    }
+
+    size_remaining = autobuf->size - autobuf->len;
+
+    rc = vsnprintf(start, size_remaining, format, ap2);
+    if ((rc < 0) || (rc >= size_remaining)) {
+      goto error_out;
     }
-    vsnprintf(autobuf->buf + autobuf->len, autobuf->size - autobuf->len, format, ap2);
   }
+
+  autobuf->len += rc;
   va_end(ap2);
-  autobuf->len = min_size;
   return 0;
+
+  error_out: autobuf->buf[autobuf->len] = '\0';
+  va_end(ap2);
+  return -1;
 }
 
 int