124ae6294SZachary Turner //===-- VASPrintf.cpp -------------------------------------------*- C++ -*-===//
224ae6294SZachary Turner //
324ae6294SZachary Turner //                     The LLVM Compiler Infrastructure
424ae6294SZachary Turner //
524ae6294SZachary Turner // This file is distributed under the University of Illinois Open Source
624ae6294SZachary Turner // License. See LICENSE.TXT for details.
724ae6294SZachary Turner //
824ae6294SZachary Turner //===----------------------------------------------------------------------===//
924ae6294SZachary Turner 
10d9c0e15fSZachary Turner #include "lldb/Utility/VASPrintf.h"
1124ae6294SZachary Turner 
1224ae6294SZachary Turner #include "llvm/ADT/SmallString.h"
1324ae6294SZachary Turner 
1424ae6294SZachary Turner using namespace lldb_private;
1524ae6294SZachary Turner 
1624ae6294SZachary Turner bool lldb_private::VASprintf(llvm::SmallVectorImpl<char> &buf, const char *fmt,
1724ae6294SZachary Turner                              va_list args) {
1824ae6294SZachary Turner   llvm::SmallString<16> error("<Encoding error>");
1924ae6294SZachary Turner   bool result = true;
2024ae6294SZachary Turner 
2124ae6294SZachary Turner   // Copy in case our first call to vsnprintf doesn't fit into our buffer
2224ae6294SZachary Turner   va_list copy_args;
2324ae6294SZachary Turner   va_copy(copy_args, args);
2424ae6294SZachary Turner 
2524ae6294SZachary Turner   buf.resize(buf.capacity());
2624ae6294SZachary Turner   // Write up to `capacity` bytes, ignoring the current size.
2724ae6294SZachary Turner   int length = ::vsnprintf(buf.data(), buf.size(), fmt, args);
2824ae6294SZachary Turner   if (length < 0) {
2924ae6294SZachary Turner     buf = error;
3024ae6294SZachary Turner     result = false;
3124ae6294SZachary Turner     goto finish;
3224ae6294SZachary Turner   }
3324ae6294SZachary Turner 
34*3bc714b2SZachary Turner   if (size_t(length) >= buf.size()) {
3524ae6294SZachary Turner     // The error formatted string didn't fit into our buffer, resize it
3624ae6294SZachary Turner     // to the exact needed size, and retry
3724ae6294SZachary Turner     buf.resize(length + 1);
3824ae6294SZachary Turner     length = ::vsnprintf(buf.data(), buf.size(), fmt, copy_args);
3924ae6294SZachary Turner     if (length < 0) {
4024ae6294SZachary Turner       buf = error;
4124ae6294SZachary Turner       result = false;
4224ae6294SZachary Turner       goto finish;
4324ae6294SZachary Turner     }
44*3bc714b2SZachary Turner     assert(size_t(length) < buf.size());
4524ae6294SZachary Turner   }
4624ae6294SZachary Turner   buf.resize(length);
4724ae6294SZachary Turner 
4824ae6294SZachary Turner finish:
4924ae6294SZachary Turner   va_end(args);
5024ae6294SZachary Turner   va_end(copy_args);
5124ae6294SZachary Turner   return result;
5224ae6294SZachary Turner }
53