diff options
Diffstat (limited to 'lldb/source/Utility/VASprintf.cpp')
| -rw-r--r-- | lldb/source/Utility/VASprintf.cpp | 55 | 
1 files changed, 55 insertions, 0 deletions
diff --git a/lldb/source/Utility/VASprintf.cpp b/lldb/source/Utility/VASprintf.cpp new file mode 100644 index 000000000000..2ee0f6676fa7 --- /dev/null +++ b/lldb/source/Utility/VASprintf.cpp @@ -0,0 +1,55 @@ +//===-- VASprintf.cpp -------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Utility/VASPrintf.h" + +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" + +#include <assert.h> +#include <stdarg.h> +#include <stdio.h> + +bool lldb_private::VASprintf(llvm::SmallVectorImpl<char> &buf, const char *fmt, +                             va_list args) { +  llvm::SmallString<16> error("<Encoding error>"); +  bool result = true; + +  // Copy in case our first call to vsnprintf doesn't fit into our buffer +  va_list copy_args; +  va_copy(copy_args, args); + +  buf.resize(buf.capacity()); +  // Write up to `capacity` bytes, ignoring the current size. +  int length = ::vsnprintf(buf.data(), buf.size(), fmt, args); +  if (length < 0) { +    buf = error; +    result = false; +    goto finish; +  } + +  if (size_t(length) >= buf.size()) { +    // The error formatted string didn't fit into our buffer, resize it to the +    // exact needed size, and retry +    buf.resize(length + 1); +    length = ::vsnprintf(buf.data(), buf.size(), fmt, copy_args); +    if (length < 0) { +      buf = error; +      result = false; +      goto finish; +    } +    assert(size_t(length) < buf.size()); +  } +  buf.resize(length); + +finish: +  va_end(args); +  va_end(copy_args); +  return result; +}  | 
