Finish breaking the dependency from Utility.

Differential Revision: https://reviews.llvm.org/D29964

llvm-svn: 295368
diff --git a/lldb/source/Host/CMakeLists.txt b/lldb/source/Host/CMakeLists.txt
index 525e6df..5f011bd 100644
--- a/lldb/source/Host/CMakeLists.txt
+++ b/lldb/source/Host/CMakeLists.txt
@@ -27,6 +27,7 @@
   common/OptionParser.cpp
   common/PipeBase.cpp
   common/ProcessRunLock.cpp
+  common/PseudoTerminal.cpp
   common/Socket.cpp
   common/SocketAddress.cpp
   common/SoftwareBreakpoint.cpp
diff --git a/lldb/source/Utility/PseudoTerminal.cpp b/lldb/source/Host/common/PseudoTerminal.cpp
similarity index 98%
rename from lldb/source/Utility/PseudoTerminal.cpp
rename to lldb/source/Host/common/PseudoTerminal.cpp
index 4d99a56..58c32e4 100644
--- a/lldb/source/Utility/PseudoTerminal.cpp
+++ b/lldb/source/Host/common/PseudoTerminal.cpp
@@ -7,7 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "lldb/Utility/PseudoTerminal.h"
+#include "lldb/Host/PseudoTerminal.h"
 #include "lldb/Host/Config.h"
 
 #include <errno.h>
@@ -112,8 +112,7 @@
   return true;
 #else
   if (error_str)
-    ::snprintf(error_str, error_len, "%s",
-               "pseudo terminal not supported");
+    ::snprintf(error_str, error_len, "%s", "pseudo terminal not supported");
   return false;
 #endif
 }
diff --git a/lldb/source/Interpreter/ScriptInterpreter.cpp b/lldb/source/Interpreter/ScriptInterpreter.cpp
index defa23a..03087ed 100644
--- a/lldb/source/Interpreter/ScriptInterpreter.cpp
+++ b/lldb/source/Interpreter/ScriptInterpreter.cpp
@@ -14,9 +14,9 @@
 #include <string>
 
 #include "lldb/Core/StringList.h"
+#include "lldb/Host/PseudoTerminal.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Utility/Error.h"
-#include "lldb/Utility/PseudoTerminal.h"
 #include "lldb/Utility/Stream.h"
 
 using namespace lldb;
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
index 772b1f3..478d482 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
@@ -19,10 +19,10 @@
 #include <thread>
 // Other libraries and framework includes
 // Project includes
+#include "lldb/Host/PseudoTerminal.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Utility/Error.h"
 #include "lldb/Utility/LLDBAssert.h"
-#include "lldb/Utility/PseudoTerminal.h"
 #include "lldb/Utility/StreamString.h"
 #include "llvm/Support/Threading.h"
 
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.mm b/lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.mm
index 233c548..de92aa0 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.mm
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.mm
@@ -16,8 +16,8 @@
 #include <CoreFoundation/CoreFoundation.h>
 #include <Foundation/Foundation.h>
 // Project includes
+#include "lldb/Host/PseudoTerminal.h"
 #include "lldb/Target/FileAction.h"
-#include "lldb/Utility/PseudoTerminal.h"
 
 #include "llvm/ADT/StringRef.h"
 
diff --git a/lldb/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp b/lldb/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp
index 3a7396f..cf00387 100644
--- a/lldb/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp
+++ b/lldb/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp
@@ -31,9 +31,9 @@
 #include "lldb/lldb-enumerations.h"
 
 #include "lldb/Core/Log.h"
+#include "lldb/Host/PseudoTerminal.h"
 #include "lldb/Target/ProcessLaunchInfo.h"
 #include "lldb/Utility/Error.h"
-#include "lldb/Utility/PseudoTerminal.h"
 #include "lldb/Utility/StreamString.h"
 
 #include "CFBundle.h"
diff --git a/lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp b/lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp
index 0c61239..f33bbb9 100644
--- a/lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp
+++ b/lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp
@@ -21,8 +21,8 @@
 // LLDB includes
 #include "lldb/Core/Log.h"
 #include "lldb/Core/State.h"
+#include "lldb/Host/PseudoTerminal.h"
 #include "lldb/Target/ProcessLaunchInfo.h"
-#include "lldb/Utility/PseudoTerminal.h"
 #include "lldb/Utility/StreamString.h"
 
 #include "CFBundle.h"
diff --git a/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
index 4361d11..872120f 100644
--- a/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
@@ -24,12 +24,12 @@
 #include "lldb/Core/RegisterValue.h"
 #include "lldb/Core/Scalar.h"
 #include "lldb/Host/Host.h"
+#include "lldb/Host/PseudoTerminal.h"
 #include "lldb/Host/ThreadLauncher.h"
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/Thread.h"
 #include "lldb/Target/UnixSignals.h"
 #include "lldb/Utility/Error.h"
-#include "lldb/Utility/PseudoTerminal.h"
 
 #include "FreeBSDThread.h"
 #include "Plugins/Process/POSIX/CrashReason.h"
diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index f7636502..f8cc121 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -29,6 +29,7 @@
 #include "lldb/Core/State.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Host/HostProcess.h"
+#include "lldb/Host/PseudoTerminal.h"
 #include "lldb/Host/ThreadLauncher.h"
 #include "lldb/Host/common/NativeBreakpoint.h"
 #include "lldb/Host/common/NativeRegisterContext.h"
@@ -41,7 +42,6 @@
 #include "lldb/Target/Target.h"
 #include "lldb/Utility/Error.h"
 #include "lldb/Utility/LLDBAssert.h"
-#include "lldb/Utility/PseudoTerminal.h"
 #include "lldb/Utility/StringExtractor.h"
 
 #include "NativeThreadLinux.h"
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index c9419f2..46abe35 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -42,6 +42,7 @@
 #include "lldb/Host/FileSpec.h"
 #include "lldb/Host/FileSystem.h"
 #include "lldb/Host/HostThread.h"
+#include "lldb/Host/PseudoTerminal.h"
 #include "lldb/Host/StringConvert.h"
 #include "lldb/Host/Symbols.h"
 #include "lldb/Host/ThreadLauncher.h"
@@ -64,7 +65,6 @@
 #include "lldb/Target/TargetList.h"
 #include "lldb/Target/ThreadPlanCallFunction.h"
 #include "lldb/Utility/CleanUp.h"
-#include "lldb/Utility/PseudoTerminal.h"
 #include "lldb/Utility/StreamString.h"
 
 // Project includes
diff --git a/lldb/source/Utility/CMakeLists.txt b/lldb/source/Utility/CMakeLists.txt
index dc0615c..d0b823b 100644
--- a/lldb/source/Utility/CMakeLists.txt
+++ b/lldb/source/Utility/CMakeLists.txt
@@ -4,7 +4,6 @@
   JSON.cpp
   LLDBAssert.cpp
   NameMatches.cpp
-  PseudoTerminal.cpp
   Range.cpp
   RegularExpression.cpp
   SelectHelper.cpp
@@ -16,9 +15,10 @@
   StringLexer.cpp
   TaskPool.cpp
   UriParser.cpp
+  VASprintf.cpp
 
   LINK_LIBS
-    lldbHost
+  # lldbUtility cannot have any dependencies
 
   LINK_COMPONENTS
     Support
diff --git a/lldb/source/Utility/Error.cpp b/lldb/source/Utility/Error.cpp
index 3b3d1fa..0b14949 100644
--- a/lldb/source/Utility/Error.cpp
+++ b/lldb/source/Utility/Error.cpp
@@ -20,8 +20,8 @@
 #include "llvm/ADT/SmallVector.h"
 
 // Project includes
-#include "lldb/Host/PosixApi.h"
 #include "lldb/Utility/Error.h"
+#include "lldb/Utility/VASPrintf.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -233,25 +233,9 @@
     if (Success())
       SetErrorToGenericError();
 
-    // Try and fit our error into a 1024 byte buffer first...
-    llvm::SmallVector<char, 1024> buf;
-    buf.resize(1024);
-    // Copy in case our first call to vsnprintf doesn't fit into our
-    // allocated buffer above
-    va_list copy_args;
-    va_copy(copy_args, args);
-    unsigned length = ::vsnprintf(buf.data(), buf.size(), format, args);
-    if (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(), format, copy_args);
-      va_end(copy_args);
-      assert(length < buf.size());
-    }
-    m_string.assign(buf.data(), length);
-    va_end(args);
-    return length;
+    llvm::SmallString<1024> buf;
+    VASprintf(buf, format, args);
+    return buf.size();
   } else {
     m_string.clear();
   }
diff --git a/lldb/source/Utility/Stream.cpp b/lldb/source/Utility/Stream.cpp
index d3c0b05..8899a43 100644
--- a/lldb/source/Utility/Stream.cpp
+++ b/lldb/source/Utility/Stream.cpp
@@ -8,8 +8,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "lldb/Utility/Stream.h"
-#include "lldb/Host/PosixApi.h"
+
 #include "lldb/Utility/Endian.h"
+#include "lldb/Utility/VASPrintf.h"
 #include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -162,36 +163,14 @@
 // Print some formatted output to the stream.
 //------------------------------------------------------------------
 size_t Stream::PrintfVarArg(const char *format, va_list args) {
-  char str[1024];
-  va_list args_copy;
+  llvm::SmallString<1024> buf;
+  VASprintf(buf, format, args);
 
-  va_copy(args_copy, args);
-
-  size_t bytes_written = 0;
-  // Try and format our string into a fixed buffer first and see if it fits
-  size_t length = ::vsnprintf(str, sizeof(str), format, args);
-  if (length < sizeof(str)) {
-    // Include the NULL termination byte for binary output
-    if (m_flags.Test(eBinary))
-      length += 1;
-    // The formatted string fit into our stack based buffer, so we can just
-    // append that to our packet
-    bytes_written = Write(str, length);
-  } else {
-    // Our stack buffer wasn't big enough to contain the entire formatted
-    // string, so lets let vasprintf create the string for us!
-    char *str_ptr = NULL;
-    length = ::vasprintf(&str_ptr, format, args_copy);
-    if (str_ptr) {
-      // Include the NULL termination byte for binary output
-      if (m_flags.Test(eBinary))
-        length += 1;
-      bytes_written = Write(str_ptr, length);
-      ::free(str_ptr);
-    }
-  }
-  va_end(args_copy);
-  return bytes_written;
+  // Include the NULL termination byte for binary output
+  size_t length = buf.size();
+  if (m_flags.Test(eBinary))
+    ++length;
+  return Write(buf.c_str(), length);
 }
 
 //------------------------------------------------------------------
@@ -358,34 +337,18 @@
 
 size_t Stream::PrintfAsRawHex8(const char *format, ...) {
   va_list args;
-  va_list args_copy;
   va_start(args, format);
-  va_copy(args_copy, args); // Copy this so we
 
-  char str[1024];
-  size_t bytes_written = 0;
-  // Try and format our string into a fixed buffer first and see if it fits
-  size_t length = ::vsnprintf(str, sizeof(str), format, args);
-  if (length < sizeof(str)) {
-    // The formatted string fit into our stack based buffer, so we can just
-    // append that to our packet
-    for (size_t i = 0; i < length; ++i)
-      bytes_written += _PutHex8(str[i], false);
-  } else {
-    // Our stack buffer wasn't big enough to contain the entire formatted
-    // string, so lets let vasprintf create the string for us!
-    char *str_ptr = NULL;
-    length = ::vasprintf(&str_ptr, format, args_copy);
-    if (str_ptr) {
-      for (size_t i = 0; i < length; ++i)
-        bytes_written += _PutHex8(str_ptr[i], false);
-      ::free(str_ptr);
-    }
-  }
+  llvm::SmallString<1024> buf;
+  VASprintf(buf, format, args);
+
+  size_t length = 0;
+  for (char C : buf)
+    length += _PutHex8(C, false);
+
   va_end(args);
-  va_end(args_copy);
 
-  return bytes_written;
+  return length;
 }
 
 size_t Stream::PutNHex8(size_t n, uint8_t uvalue) {
diff --git a/lldb/source/Utility/VASprintf.cpp b/lldb/source/Utility/VASprintf.cpp
new file mode 100644
index 0000000..cc280ec
--- /dev/null
+++ b/lldb/source/Utility/VASprintf.cpp
@@ -0,0 +1,52 @@
+//===-- VASPrintf.cpp -------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/VASprintf.h"
+
+#include "llvm/ADT/SmallString.h"
+
+using namespace lldb_private;
+
+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 (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(length < buf.size());
+  }
+  buf.resize(length);
+
+finish:
+  va_end(args);
+  va_end(copy_args);
+  return result;
+}