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" // for SmallVectorImpl 14 #include "llvm/ADT/StringRef.h" // for StringRef 15 16 #include <assert.h> // for assert 17 #include <stdarg.h> // for va_end, va_list, va_copy 18 #include <stdio.h> // for vsnprintf, size_t 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 40 // to the 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