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