aboutsummaryrefslogtreecommitdiff
path: root/source/Utility/VASprintf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Utility/VASprintf.cpp')
-rw-r--r--source/Utility/VASprintf.cpp56
1 files changed, 56 insertions, 0 deletions
diff --git a/source/Utility/VASprintf.cpp b/source/Utility/VASprintf.cpp
new file mode 100644
index 000000000000..e950fb75cfa0
--- /dev/null
+++ b/source/Utility/VASprintf.cpp
@@ -0,0 +1,56 @@
+//===-- VASPrintf.cpp -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/VASPrintf.h"
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h" // for SmallVectorImpl
+#include "llvm/ADT/StringRef.h" // for StringRef
+
+#include <assert.h> // for assert
+#include <stdarg.h> // for va_end, va_list, va_copy
+#include <stdio.h> // for vsnprintf, size_t
+
+bool lldb_private::VASprintf(llvm::SmallVectorImpl<char> &buf, const char *fmt,
+ va_list args) {
+ llvm::SmallString<16> error("<Encoding error>");
+ bool result = true;
+
+ // Copy in case our first call to vsnprintf doesn't fit into our buffer
+ va_list copy_args;
+ va_copy(copy_args, args);
+
+ buf.resize(buf.capacity());
+ // Write up to `capacity` bytes, ignoring the current size.
+ int length = ::vsnprintf(buf.data(), buf.size(), fmt, args);
+ if (length < 0) {
+ buf = error;
+ result = false;
+ goto finish;
+ }
+
+ if (size_t(length) >= buf.size()) {
+ // The error formatted string didn't fit into our buffer, resize it
+ // to the exact needed size, and retry
+ buf.resize(length + 1);
+ length = ::vsnprintf(buf.data(), buf.size(), fmt, copy_args);
+ if (length < 0) {
+ buf = error;
+ result = false;
+ goto finish;
+ }
+ assert(size_t(length) < buf.size());
+ }
+ buf.resize(length);
+
+finish:
+ va_end(args);
+ va_end(copy_args);
+ return result;
+}