<div dir="ltr"><span style="font-size:13px">> Should a unittest really have debug printfs?  </span><br><div><span style="font-size:13px"><br></span></div><div>Those are behind a define.  edit line is inherently about converting input to output, and when we layer in auto-tabbing, auto-completion, etc. it is critical in test development to see how these develop.  Every single touch of this test is going to involve flipping them on and off, so from a workflow perspective, having the define (and usually turned off) for the debug printing way trumps purity of carrying that debug content that is usually #ifdef'd out.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Oct 30, 2015 at 9:40 AM, Todd Fiala <span dir="ltr"><<a href="mailto:todd.fiala@gmail.com" target="_blank">todd.fiala@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><span class="">> <span style="font-size:13px">What are all these setenv lines for?</span><div><br></div></span><div>libedit requires a TERM to know how to deal with the screen.  We can't talk to libedit if it can't figure out what kind of terminal it is working with.</div><span class=""><div><br></div><div><span style="font-size:13px">> Another option is to use TEST_F instead of TEST(), and then declare a class with Setup() and TearDown() methods, and do the setenv() in the setup method.</span></div><div><br></div></span><div>I am planning on doing that.  I have another few tests I am writing.  I have a "reduce duplication" XP style phase that will eliminate that.  Good catch.  I should have done it at my second test.<br><div><br></div></div></div><div class="gmail_extra"><div><div class="h5"><br><div class="gmail_quote">On Thu, Oct 29, 2015 at 11:26 PM, Zachary Turner <span dir="ltr"><<a href="mailto:zturner@google.com" target="_blank">zturner@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><br><div class="gmail_quote"><div><div><div dir="ltr">On Thu, Oct 29, 2015 at 7:57 PM Todd Fiala via lldb-commits <<a href="mailto:lldb-commits@lists.llvm.org" target="_blank">lldb-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: tfiala<br>
Date: Thu Oct 29 21:54:52 2015<br>
New Revision: 251681<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=251681&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=251681&view=rev</a><br>
Log:<br>
Added real editline tests.<br>
<br>
These are two simple tests that make sure single line and<br>
multiline content are processed and received by Editline.cpp.<br>
<br>
Fancier tests to come...<br>
<br>
Modified:<br>
    lldb/trunk/lldb.xcodeproj/project.pbxproj<br>
    lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-gtest.xcscheme<br>
    lldb/trunk/source/Host/CMakeLists.txt<br>
    lldb/trunk/unittests/Editline/EditlineTest.cpp<br>
<br>
Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=251681&r1=251680&r2=251681&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=251681&r1=251680&r2=251681&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)<br>
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Thu Oct 29 21:54:52 2015<br>
@@ -909,13 +909,6 @@<br>
 /* End PBXBuildFile section */<br>
<br>
 /* Begin PBXContainerItemProxy section */<br>
-               2326CF411BDD636100A5CEAC /* PBXContainerItemProxy */ = {<br>
-                       isa = PBXContainerItemProxy;<br>
-                       containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;<br>
-                       proxyType = 1;<br>
-                       remoteGlobalIDString = 26680206115FD0ED008E1FE4;<br>
-                       remoteInfo = LLDB;<br>
-               };<br>
                235AFBC1199BC70700897A4B /* PBXContainerItemProxy */ = {<br>
                        isa = PBXContainerItemProxy;<br>
                        containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;<br>
@@ -937,6 +930,13 @@<br>
                        remoteGlobalIDString = 456F67721AD46CE9002850C2;<br>
                        remoteInfo = "debugserver-mini";<br>
                };<br>
+               23AB8B6A1BDF513B008BF3B0 /* PBXContainerItemProxy */ = {<br>
+                       isa = PBXContainerItemProxy;<br>
+                       containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;<br>
+                       proxyType = 1;<br>
+                       remoteGlobalIDString = 2689FFC913353D7A00698AC0;<br>
+                       remoteInfo = "lldb-core";<br>
+               };<br>
                262CFC7111A450CB00946C6C /* PBXContainerItemProxy */ = {<br>
                        isa = PBXContainerItemProxy;<br>
                        containerPortal = 265E9BE1115C2BAA00D0DCCB /* debugserver.xcodeproj */;<br>
@@ -5831,7 +5831,7 @@<br>
                        buildRules = (<br>
                        );<br>
                        dependencies = (<br>
-                               2326CF421BDD636100A5CEAC /* PBXTargetDependency */,<br>
+                               23AB8B6B1BDF513B008BF3B0 /* PBXTargetDependency */,<br>
                        );<br>
                        name = "lldb-gtest";<br>
                        productName = "lldb-gtest";<br>
@@ -6965,11 +6965,6 @@<br>
 /* End PBXSourcesBuildPhase section */<br>
<br>
 /* Begin PBXTargetDependency section */<br>
-               2326CF421BDD636100A5CEAC /* PBXTargetDependency */ = {<br>
-                       isa = PBXTargetDependency;<br>
-                       target = 26680206115FD0ED008E1FE4 /* LLDB */;<br>
-                       targetProxy = 2326CF411BDD636100A5CEAC /* PBXContainerItemProxy */;<br>
-               };<br>
                235AFBC2199BC70700897A4B /* PBXTargetDependency */ = {<br>
                        isa = PBXTargetDependency;<br>
                        target = 26F5C26910F3D9A4009D5894 /* lldb-tool */;<br>
@@ -6980,6 +6975,11 @@<br>
                        target = 235AFBB5199BC6AD00897A4B /* Linux */;<br>
                        targetProxy = 235AFBC3199BC70B00897A4B /* PBXContainerItemProxy */;<br>
                };<br>
+               23AB8B6B1BDF513B008BF3B0 /* PBXTargetDependency */ = {<br>
+                       isa = PBXTargetDependency;<br>
+                       target = 2689FFC913353D7A00698AC0 /* lldb-core */;<br>
+                       targetProxy = 23AB8B6A1BDF513B008BF3B0 /* PBXContainerItemProxy */;<br>
+               };<br>
                262CFC7211A450CB00946C6C /* PBXTargetDependency */ = {<br>
                        isa = PBXTargetDependency;<br>
                        name = debugserver;<br>
@@ -7404,31 +7404,13 @@<br>
                239504D81BDD451400963CEA /* Debug */ = {<br>
                        isa = XCBuildConfiguration;<br>
                        buildSettings = {<br>
-                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";<br>
-                               CLANG_ENABLE_MODULES = YES;<br>
-                               CLANG_ENABLE_OBJC_ARC = YES;<br>
-                               CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;<br>
-                               CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;<br>
-                               CODE_SIGN_IDENTITY = "-";<br>
-                               ENABLE_TESTABILITY = YES;<br>
                                FRAMEWORK_SEARCH_PATHS = (<br>
                                        "$(inherited)",<br>
                                        "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"",<br>
                                        "$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks",<br>
                                );<br>
-                               GCC_C_LANGUAGE_STANDARD = gnu99;<br>
-                               GCC_DYNAMIC_NO_PIC = NO;<br>
-                               GCC_NO_COMMON_BLOCKS = YES;<br>
-                               GCC_PREPROCESSOR_DEFINITIONS = (<br>
-                                       "DEBUG=1",<br>
-                                       "$(inherited)",<br>
-                               );<br>
-                               GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;<br>
-                               GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;<br>
                                LLDB_GTESTS_CFLAGS = "-I $(LLVM_SOURCE_DIR)/utils/unittest/googletest/include -I $(LLVM_SOURCE_DIR)/include -I $(LLVM_BUILD_DIR)/x86_64/include -I include -I source -I $(PYTHON_FRAMEWORK_PATH)/Headers";<br>
                                LLDB_GTESTS_LDFLAGS = "$(LLVM_BUILD_DIR)/x86_64/$(LLVM_CONFIGURATION)/lib/libgtest.a -L $(PYTHON_FRAMEWORK_PATH)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib -l python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)";<br>
-                               MACOSX_DEPLOYMENT_TARGET = 10.11;<br>
-                               MTL_ENABLE_DEBUG_INFO = YES;<br>
                                OTHER_CFLAGS = (<br>
                                        "-flimit-debug-info",<br>
                                        "-Wparentheses",<br>
@@ -7453,38 +7435,19 @@<br>
                                        "$(LLDB_GTESTS_LDFLAGS)",<br>
                                );<br>
                                PRODUCT_NAME = "$(TARGET_NAME)";<br>
-                               SDKROOT = macosx;<br>
                        };<br>
                        name = Debug;<br>
                };<br>
                239504D91BDD451400963CEA /* DebugClang */ = {<br>
                        isa = XCBuildConfiguration;<br>
                        buildSettings = {<br>
-                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";<br>
-                               CLANG_ENABLE_MODULES = YES;<br>
-                               CLANG_ENABLE_OBJC_ARC = YES;<br>
-                               CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;<br>
-                               CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;<br>
-                               CODE_SIGN_IDENTITY = "-";<br>
-                               ENABLE_TESTABILITY = YES;<br>
                                FRAMEWORK_SEARCH_PATHS = (<br>
                                        "$(inherited)",<br>
                                        "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"",<br>
                                        "$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks",<br>
                                );<br>
-                               GCC_C_LANGUAGE_STANDARD = gnu99;<br>
-                               GCC_DYNAMIC_NO_PIC = NO;<br>
-                               GCC_NO_COMMON_BLOCKS = YES;<br>
-                               GCC_PREPROCESSOR_DEFINITIONS = (<br>
-                                       "DEBUG=1",<br>
-                                       "$(inherited)",<br>
-                               );<br>
-                               GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;<br>
-                               GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;<br>
                                LLDB_GTESTS_CFLAGS = "-I $(LLVM_SOURCE_DIR)/utils/unittest/googletest/include -I $(LLVM_SOURCE_DIR)/include -I $(LLVM_BUILD_DIR)/x86_64/include -I include -I source -I $(PYTHON_FRAMEWORK_PATH)/Headers";<br>
                                LLDB_GTESTS_LDFLAGS = "$(LLVM_BUILD_DIR)/x86_64/$(LLVM_CONFIGURATION)/lib/libgtest.a -L $(PYTHON_FRAMEWORK_PATH)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib -l python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)";<br>
-                               MACOSX_DEPLOYMENT_TARGET = 10.11;<br>
-                               MTL_ENABLE_DEBUG_INFO = YES;<br>
                                OTHER_CFLAGS = (<br>
                                        "-flimit-debug-info",<br>
                                        "-Wparentheses",<br>
@@ -7509,34 +7472,19 @@<br>
                                        "$(LLDB_GTESTS_LDFLAGS)",<br>
                                );<br>
                                PRODUCT_NAME = "$(TARGET_NAME)";<br>
-                               SDKROOT = macosx;<br>
                        };<br>
                        name = DebugClang;<br>
                };<br>
                239504DA1BDD451400963CEA /* Release */ = {<br>
                        isa = XCBuildConfiguration;<br>
                        buildSettings = {<br>
-                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";<br>
-                               CLANG_ENABLE_MODULES = YES;<br>
-                               CLANG_ENABLE_OBJC_ARC = YES;<br>
-                               CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;<br>
-                               CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;<br>
-                               CODE_SIGN_IDENTITY = "-";<br>
-                               DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";<br>
-                               ENABLE_NS_ASSERTIONS = NO;<br>
                                FRAMEWORK_SEARCH_PATHS = (<br>
                                        "$(inherited)",<br>
                                        "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"",<br>
                                        "$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks",<br>
                                );<br>
-                               GCC_C_LANGUAGE_STANDARD = gnu99;<br>
-                               GCC_NO_COMMON_BLOCKS = YES;<br>
-                               GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;<br>
-                               GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;<br>
                                LLDB_GTESTS_CFLAGS = "-I $(LLVM_SOURCE_DIR)/utils/unittest/googletest/include -I $(LLVM_SOURCE_DIR)/include -I $(LLVM_BUILD_DIR)/x86_64/include -I include -I source -I $(PYTHON_FRAMEWORK_PATH)/Headers";<br>
                                LLDB_GTESTS_LDFLAGS = "$(LLVM_BUILD_DIR)/x86_64/$(LLVM_CONFIGURATION)/lib/libgtest.a -L $(PYTHON_FRAMEWORK_PATH)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib -l python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)";<br>
-                               MACOSX_DEPLOYMENT_TARGET = 10.11;<br>
-                               MTL_ENABLE_DEBUG_INFO = NO;<br>
                                OTHER_CFLAGS = (<br>
                                        "-flimit-debug-info",<br>
                                        "-Wparentheses",<br>
@@ -7561,34 +7509,19 @@<br>
                                        "$(LLDB_GTESTS_LDFLAGS)",<br>
                                );<br>
                                PRODUCT_NAME = "$(TARGET_NAME)";<br>
-                               SDKROOT = macosx;<br>
                        };<br>
                        name = Release;<br>
                };<br>
                239504DB1BDD451400963CEA /* BuildAndIntegration */ = {<br>
                        isa = XCBuildConfiguration;<br>
                        buildSettings = {<br>
-                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";<br>
-                               CLANG_ENABLE_MODULES = YES;<br>
-                               CLANG_ENABLE_OBJC_ARC = YES;<br>
-                               CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;<br>
-                               CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;<br>
-                               CODE_SIGN_IDENTITY = "-";<br>
-                               DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";<br>
-                               ENABLE_NS_ASSERTIONS = NO;<br>
                                FRAMEWORK_SEARCH_PATHS = (<br>
                                        "$(inherited)",<br>
                                        "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"",<br>
                                        "$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks",<br>
                                );<br>
-                               GCC_C_LANGUAGE_STANDARD = gnu99;<br>
-                               GCC_NO_COMMON_BLOCKS = YES;<br>
-                               GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;<br>
-                               GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;<br>
                                LLDB_GTESTS_CFLAGS = "-I $(LLVM_SOURCE_DIR)/utils/unittest/googletest/include -I $(LLVM_SOURCE_DIR)/include -I $(LLVM_BUILD_DIR)/x86_64/include -I include -I source -I $(PYTHON_FRAMEWORK_PATH)/Headers";<br>
                                LLDB_GTESTS_LDFLAGS = "$(LLVM_BUILD_DIR)/x86_64/$(LLVM_CONFIGURATION)/lib/libgtest.a -L $(PYTHON_FRAMEWORK_PATH)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib -l python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)";<br>
-                               MACOSX_DEPLOYMENT_TARGET = 10.11;<br>
-                               MTL_ENABLE_DEBUG_INFO = NO;<br>
                                OTHER_CFLAGS = (<br>
                                        "-flimit-debug-info",<br>
                                        "-Wparentheses",<br>
@@ -7613,7 +7546,6 @@<br>
                                        "$(LLDB_GTESTS_LDFLAGS)",<br>
                                );<br>
                                PRODUCT_NAME = "$(TARGET_NAME)";<br>
-                               SDKROOT = macosx;<br>
                        };<br>
                        name = BuildAndIntegration;<br>
                };<br>
<br>
Modified: lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-gtest.xcscheme<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-gtest.xcscheme?rev=251681&r1=251680&r2=251681&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-gtest.xcscheme?rev=251681&r1=251680&r2=251681&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-gtest.xcscheme (original)<br>
+++ lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-gtest.xcscheme Thu Oct 29 21:54:52 2015<br>
@@ -42,7 +42,7 @@<br>
       </AdditionalOptions><br>
    </TestAction><br>
    <LaunchAction<br>
-      buildConfiguration = "DebugClang"<br>
+      buildConfiguration = "Debug"<br>
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"<br>
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"<br>
       launchStyle = "0"<br>
<br>
Modified: lldb/trunk/source/Host/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/CMakeLists.txt?rev=251681&r1=251680&r2=251681&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/CMakeLists.txt?rev=251681&r1=251680&r2=251681&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/source/Host/CMakeLists.txt (original)<br>
+++ lldb/trunk/source/Host/CMakeLists.txt Thu Oct 29 21:54:52 2015<br>
@@ -170,6 +170,19 @@ if (${get_python_libdir})<br>
   endif()<br>
 endif()<br>
<br>
+if (${get_python_libdir})<br>
+  # Call a python script to gather the arch-specific libdir for<br>
+  # modules like the lldb module.<br>
+  execute_process(<br>
+    COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../../scripts/get_relative_lib_dir.py<br>
+    RESULT_VARIABLE get_libdir_status<br>
+    OUTPUT_VARIABLE relative_libdir<br>
+    )<br>
+  if (get_libdir_status EQUAL 0)<br>
+    add_definitions(-DLLDB_PYTHON_RELATIVE_LIBDIR="${relative_libdir}")<br>
+  endif()<br>
+endif()<br>
+<br>
 add_lldb_library(lldbHost ${HOST_SOURCES})<br>
<br>
 if (CMAKE_SYSTEM_NAME MATCHES "NetBSD")<br>
<br>
Modified: lldb/trunk/unittests/Editline/EditlineTest.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Editline/EditlineTest.cpp?rev=251681&r1=251680&r2=251681&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Editline/EditlineTest.cpp?rev=251681&r1=251680&r2=251681&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/unittests/Editline/EditlineTest.cpp (original)<br>
+++ lldb/trunk/unittests/Editline/EditlineTest.cpp Thu Oct 29 21:54:52 2015<br>
@@ -7,9 +7,362 @@<br>
 //<br>
 //===----------------------------------------------------------------------===//<br>
<br>
+#ifndef LLDB_DISABLE_LIBEDIT<br>
+<br>
+#define EDITLINE_TEST_DUMP_OUTPUT 0<br>
+<br>
+#include <stdio.h><br>
+#include <unistd.h><br>
+<br>
+#include <memory><br>
+#include <thread><br>
+<br>
 #include "gtest/gtest.h"<br>
<br>
-TEST(EditlineTest, BasicTest)<br>
+#include "lldb/Core/Error.h"<br>
+#include "lldb/Core/StringList.h"<br>
+#include "lldb/Host/Editline.h"<br>
+#include "lldb/Host/Pipe.h"<br>
+#include "lldb/Utility/PseudoTerminal.h"<br>
+<br>
+namespace<br>
 {<br>
-    EXPECT_TRUE(true);<br>
+    const size_t TIMEOUT_MILLIS = 5000;<br>
 }<br>
+<br>
+class FilePointer<br>
+{<br>
+public:<br>
+<br>
+    FilePointer () = delete;<br>
+<br>
+    FilePointer (const FilePointer&) = delete;<br>
+<br>
+    FilePointer (FILE *file_p)<br>
+    : _file_p (file_p)<br>
+    {<br>
+    }<br>
+<br>
+    ~FilePointer ()<br>
+    {<br>
+        if (_file_p != nullptr)<br>
+        {<br>
+            const int close_result = fclose (_file_p);<br>
+            EXPECT_EQ(0, close_result);<br>
+        }<br>
+    }<br>
+<br>
+    operator FILE* ()<br>
+    {<br>
+        return _file_p;<br>
+    }<br>
+<br>
+private:<br>
+<br>
+    FILE *_file_p;<br>
+<br>
+};<br>
+<br>
+/**<br>
+ Wraps an Editline class, providing a simple way to feed<br>
+ input (as if from the keyboard) and receive output from Editline.<br>
+ */<br>
+class EditlineAdapter<br>
+{<br>
+public:<br>
+<br>
+    EditlineAdapter ();<br>
+<br>
+    void<br>
+    CloseInput ();<br>
+<br>
+    bool<br>
+    IsValid () const<br>
+    {<br>
+        return _editline_sp.get () != nullptr;<br>
+    }<br>
+<br>
+    lldb_private::Editline&<br>
+    GetEditline ()<br>
+    {<br>
+        return *_editline_sp;<br>
+    }<br>
+<br>
+    bool<br>
+    SendLine (const std::string &line);<br>
+<br>
+    bool<br>
+    SendLines (const std::vector<std::string> &lines);<br>
+<br>
+    bool<br>
+    GetLine (std::string &line, bool &interrupted, size_t timeout_millis);<br>
+<br>
+    bool<br>
+    GetLines (lldb_private::StringList &lines, bool &interrupted, size_t timeout_millis);<br>
+<br>
+    void<br>
+    ConsumeAllOutput ();<br>
+<br>
+private:<br>
+<br>
+    static bool<br>
+    IsInputComplete (<br>
+        lldb_private::Editline * editline,<br>
+        lldb_private::StringList & lines,<br>
+        void * baton);<br>
+<br>
+    std::unique_ptr<lldb_private::Editline> _editline_sp;<br>
+<br>
+    lldb_utility::PseudoTerminal _pty;<br>
+    int _pty_master_fd;<br>
+    int _pty_slave_fd;<br>
+<br>
+    std::unique_ptr<FilePointer> _el_slave_file;<br>
+};<br>
+<br>
+EditlineAdapter::EditlineAdapter () :<br>
+    _editline_sp (),<br>
+    _pty (),<br>
+    _pty_master_fd (-1),<br>
+    _pty_slave_fd (-1),<br>
+    _el_slave_file ()<br>
+{<br>
+    lldb_private::Error error;<br>
+<br>
+    // Open the first master pty available.<br>
+    char error_string[256];<br>
+    error_string[0] = '\0';<br>
+    if (!_pty.OpenFirstAvailableMaster (O_RDWR, error_string, sizeof (error_string)))<br>
+    {<br>
+        fprintf(stderr, "failed to open first available master pty: '%s'\n", error_string);<br>
+        return;<br>
+    }<br>
+<br>
+    // Grab the master fd.  This is a file descriptor we will:<br>
+    // (1) write to when we want to send input to editline.<br>
+    // (2) read from when we want to see what editline sends back.<br>
+    _pty_master_fd = _pty.GetMasterFileDescriptor();<br>
+<br>
+    // Open the corresponding slave pty.<br>
+    if (!_pty.OpenSlave (O_RDWR, error_string, sizeof (error_string)))<br>
+    {<br>
+        fprintf(stderr, "failed to open slave pty: '%s'\n", error_string);<br>
+        return;<br>
+    }<br>
+    _pty_slave_fd = _pty.GetSlaveFileDescriptor();<br>
+<br>
+    _el_slave_file.reset (new FilePointer (fdopen (_pty_slave_fd, "rw")));<br>
+    EXPECT_FALSE (nullptr == *_el_slave_file);<br>
+    if (*_el_slave_file == nullptr)<br>
+        return;<br>
+<br>
+    // Create an Editline instance.<br>
+    _editline_sp.reset (new lldb_private::Editline("gtest editor", *_el_slave_file, *_el_slave_file, *_el_slave_file, false));<br>
+    _editline_sp->SetPrompt ("> ");<br>
+<br>
+    // Hookup our input complete callback.<br>
+    _editline_sp->SetIsInputCompleteCallback(IsInputComplete, this);<br>
+}<br>
+<br>
+void<br>
+EditlineAdapter::CloseInput ()<br>
+{<br>
+    if (_el_slave_file != nullptr)<br>
+        _el_slave_file.reset (nullptr);<br>
+}<br>
+<br>
+bool<br>
+EditlineAdapter::SendLine (const std::string &line)<br>
+{<br>
+    // Ensure we're valid before proceeding.<br>
+    if (!IsValid ())<br>
+        return false;<br>
+<br>
+    // Write the line out to the pipe connected to editline's input.<br>
+    ssize_t input_bytes_written =<br>
+        ::write (_pty_master_fd,<br>
+                 line.c_str(),<br>
+                 line.length() * sizeof (std::string::value_type));<br>
+<br>
+    const char *eoln = "\n";<br>
+    const size_t eoln_length = strlen(eoln);<br>
+    input_bytes_written =<br>
+        ::write (_pty_master_fd,<br>
+                 eoln,<br>
+                 eoln_length * sizeof (char));<br>
+<br>
+    EXPECT_EQ (eoln_length * sizeof (char), input_bytes_written);<br>
+    return eoln_length * sizeof (char) == input_bytes_written;<br>
+}<br>
+<br>
+bool<br>
+EditlineAdapter::SendLines (const std::vector<std::string> &lines)<br>
+{<br>
+    for (auto &line : lines)<br>
+    {<br>
+#if EDITLINE_TEST_DUMP_OUTPUT<br>
+        printf ("<stdin> sending line \"%s\"\n", line.c_str());<br>
+#endif<br>
+        if (!SendLine (line))<br>
+            return false;<br>
+    }<br>
+    return true;<br>
+}<br>
+<br>
+// We ignore the timeout for now.<br>
+bool<br>
+EditlineAdapter::GetLine (std::string &line, bool &interrupted, size_t /* timeout_millis */)<br>
+{<br>
+    // Ensure we're valid before proceeding.<br>
+    if (!IsValid ())<br>
+        return false;<br>
+<br>
+    _editline_sp->GetLine (line, interrupted);<br>
+    return true;<br>
+}<br>
+<br>
+bool<br>
+EditlineAdapter::GetLines (lldb_private::StringList &lines, bool &interrupted, size_t /* timeout_millis */)<br>
+{<br>
+    // Ensure we're valid before proceeding.<br>
+    if (!IsValid ())<br>
+        return false;<br>
+<br>
+    _editline_sp->GetLines (1, lines, interrupted);<br>
+    return true;<br>
+}<br>
+<br>
+bool<br>
+EditlineAdapter::IsInputComplete (<br>
+        lldb_private::Editline * editline,<br>
+        lldb_private::StringList & lines,<br>
+        void * baton)<br>
+{<br>
+    // We'll call ourselves complete if we've received a balanced set of braces.<br>
+    int start_block_count = 0;<br>
+    int brace_balance = 0;<br>
+<br>
+    for (size_t i = 0; i < lines.GetSize (); ++i)<br>
+    {<br>
+        for (auto ch : lines[i])<br>
+        {<br>
+            if (ch == '{')<br>
+            {<br>
+                ++start_block_count;<br>
+                ++brace_balance;<br>
+            }<br>
+            else if (ch == '}')<br>
+                --brace_balance;<br>
+        }<br>
+    }<br>
+<br>
+    return (start_block_count > 0) && (brace_balance == 0);<br>
+}<br>
+<br>
+void<br>
+EditlineAdapter::ConsumeAllOutput ()<br>
+{<br>
+    FilePointer output_file (fdopen (_pty_master_fd, "r"));<br>
+<br>
+    int ch;<br>
+    while ((ch = fgetc(output_file)) != EOF)<br>
+    {<br>
+#if EDITLINE_TEST_DUMP_OUTPUT<br>
+        char display_str[] = { 0, 0, 0 };<br>
+        switch (ch)<br>
+        {<br>
+            case '\t':<br>
+                display_str[0] = '\\';<br>
+                display_str[1] = 't';<br>
+                break;<br>
+            case '\n':<br>
+                display_str[0] = '\\';<br>
+                display_str[1] = 'n';<br>
+                break;<br>
+            case '\r':<br>
+                display_str[0] = '\\';<br>
+                display_str[1] = 'r';<br>
+                break;<br>
+            default:<br>
+                display_str[0] = ch;<br>
+                break;<br>
+        }<br>
+        printf ("<stdout> 0x%02x (%03d) (%s)\n", ch, ch, display_str);<br>
+        // putc(ch, stdout);<br>
+#endif<br>
+    }<br>
+}<br></blockquote></div></div><div>This strikes me as a little odd.  What's this for?  Should a unittest really have debug printfs?  </div><span><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+TEST (EditlineTest, EditlineReceivesSingleLineText)<br>
+{<br>
+    setenv ("TERM", "vt100", 1);<br></blockquote></span><div>What are all these setenv lines for?  Another option is to use TEST_F instead of TEST(), and then declare a class with Setup() and TearDown() methods, and do the setenv() in the setup method.  Then this environment variable will be set in every test run.  That said, it still feels a little dirty to have the test muck with environment variables.  How does Editline use this?</div></div></div>
</blockquote></div><br><br clear="all"><div><br></div></div></div><span class="HOEnZb"><font color="#888888">-- <br><div><div dir="ltr">-Todd</div></div>
</font></span></div>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr">-Todd</div></div>
</div>