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