1 //===-- VASPrintf.cpp -------------------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/Utility/VASPrintf.h"
11
12 #include "llvm/ADT/SmallString.h"
13 #include "llvm/ADT/SmallVector.h"
14 #include "llvm/ADT/StringRef.h"
15
16 #include <assert.h>
17 #include <stdarg.h>
18 #include <stdio.h>
19
VASprintf(llvm::SmallVectorImpl<char> & buf,const char * fmt,va_list args)20 bool lldb_private::VASprintf(llvm::SmallVectorImpl<char> &buf, const char *fmt,
21 va_list args) {
22 llvm::SmallString<16> error("<Encoding error>");
23 bool result = true;
24
25 // Copy in case our first call to vsnprintf doesn't fit into our buffer
26 va_list copy_args;
27 va_copy(copy_args, args);
28
29 buf.resize(buf.capacity());
30 // Write up to `capacity` bytes, ignoring the current size.
31 int length = ::vsnprintf(buf.data(), buf.size(), fmt, args);
32 if (length < 0) {
33 buf = error;
34 result = false;
35 goto finish;
36 }
37
38 if (size_t(length) >= buf.size()) {
39 // The error formatted string didn't fit into our buffer, resize it to the
40 // exact needed size, and retry
41 buf.resize(length + 1);
42 length = ::vsnprintf(buf.data(), buf.size(), fmt, copy_args);
43 if (length < 0) {
44 buf = error;
45 result = false;
46 goto finish;
47 }
48 assert(size_t(length) < buf.size());
49 }
50 buf.resize(length);
51
52 finish:
53 va_end(args);
54 va_end(copy_args);
55 return result;
56 }
57