1353358Sdim//===-- VASprintf.cpp -------------------------------------------*- C++ -*-===// 2317027Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6317027Sdim// 7317027Sdim//===----------------------------------------------------------------------===// 8317027Sdim 9317027Sdim#include "lldb/Utility/VASPrintf.h" 10317027Sdim 11317027Sdim#include "llvm/ADT/SmallString.h" 12344779Sdim#include "llvm/ADT/SmallVector.h" 13344779Sdim#include "llvm/ADT/StringRef.h" 14317027Sdim 15344779Sdim#include <assert.h> 16344779Sdim#include <stdarg.h> 17344779Sdim#include <stdio.h> 18317027Sdim 19317027Sdimbool lldb_private::VASprintf(llvm::SmallVectorImpl<char> &buf, const char *fmt, 20317027Sdim va_list args) { 21317027Sdim llvm::SmallString<16> error("<Encoding error>"); 22317027Sdim bool result = true; 23317027Sdim 24317027Sdim // Copy in case our first call to vsnprintf doesn't fit into our buffer 25317027Sdim va_list copy_args; 26317027Sdim va_copy(copy_args, args); 27317027Sdim 28317027Sdim buf.resize(buf.capacity()); 29317027Sdim // Write up to `capacity` bytes, ignoring the current size. 30317027Sdim int length = ::vsnprintf(buf.data(), buf.size(), fmt, args); 31317027Sdim if (length < 0) { 32317027Sdim buf = error; 33317027Sdim result = false; 34317027Sdim goto finish; 35317027Sdim } 36317027Sdim 37317027Sdim if (size_t(length) >= buf.size()) { 38341825Sdim // The error formatted string didn't fit into our buffer, resize it to the 39341825Sdim // exact needed size, and retry 40317027Sdim buf.resize(length + 1); 41317027Sdim length = ::vsnprintf(buf.data(), buf.size(), fmt, copy_args); 42317027Sdim if (length < 0) { 43317027Sdim buf = error; 44317027Sdim result = false; 45317027Sdim goto finish; 46317027Sdim } 47317027Sdim assert(size_t(length) < buf.size()); 48317027Sdim } 49317027Sdim buf.resize(length); 50317027Sdim 51317027Sdimfinish: 52317027Sdim va_end(args); 53317027Sdim va_end(copy_args); 54317027Sdim return result; 55317027Sdim} 56