]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Utility/VASprintf.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Utility / VASprintf.cpp
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
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 }