[Lldb-commits] [lldb] r251681 - Added real editline tests.

Todd Fiala via lldb-commits lldb-commits at lists.llvm.org
Thu Oct 29 19:54:53 PDT 2015


Author: tfiala
Date: Thu Oct 29 21:54:52 2015
New Revision: 251681

URL: http://llvm.org/viewvc/llvm-project?rev=251681&view=rev
Log:
Added real editline tests.

These are two simple tests that make sure single line and
multiline content are processed and received by Editline.cpp.

Fancier tests to come...

Modified:
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-gtest.xcscheme
    lldb/trunk/source/Host/CMakeLists.txt
    lldb/trunk/unittests/Editline/EditlineTest.cpp

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=251681&r1=251680&r2=251681&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Thu Oct 29 21:54:52 2015
@@ -909,13 +909,6 @@
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
-		2326CF411BDD636100A5CEAC /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
-			proxyType = 1;
-			remoteGlobalIDString = 26680206115FD0ED008E1FE4;
-			remoteInfo = LLDB;
-		};
 		235AFBC1199BC70700897A4B /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
 			containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
@@ -937,6 +930,13 @@
 			remoteGlobalIDString = 456F67721AD46CE9002850C2;
 			remoteInfo = "debugserver-mini";
 		};
+		23AB8B6A1BDF513B008BF3B0 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 2689FFC913353D7A00698AC0;
+			remoteInfo = "lldb-core";
+		};
 		262CFC7111A450CB00946C6C /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
 			containerPortal = 265E9BE1115C2BAA00D0DCCB /* debugserver.xcodeproj */;
@@ -5831,7 +5831,7 @@
 			buildRules = (
 			);
 			dependencies = (
-				2326CF421BDD636100A5CEAC /* PBXTargetDependency */,
+				23AB8B6B1BDF513B008BF3B0 /* PBXTargetDependency */,
 			);
 			name = "lldb-gtest";
 			productName = "lldb-gtest";
@@ -6965,11 +6965,6 @@
 /* End PBXSourcesBuildPhase section */
 
 /* Begin PBXTargetDependency section */
-		2326CF421BDD636100A5CEAC /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			target = 26680206115FD0ED008E1FE4 /* LLDB */;
-			targetProxy = 2326CF411BDD636100A5CEAC /* PBXContainerItemProxy */;
-		};
 		235AFBC2199BC70700897A4B /* PBXTargetDependency */ = {
 			isa = PBXTargetDependency;
 			target = 26F5C26910F3D9A4009D5894 /* lldb-tool */;
@@ -6980,6 +6975,11 @@
 			target = 235AFBB5199BC6AD00897A4B /* Linux */;
 			targetProxy = 235AFBC3199BC70B00897A4B /* PBXContainerItemProxy */;
 		};
+		23AB8B6B1BDF513B008BF3B0 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 2689FFC913353D7A00698AC0 /* lldb-core */;
+			targetProxy = 23AB8B6A1BDF513B008BF3B0 /* PBXContainerItemProxy */;
+		};
 		262CFC7211A450CB00946C6C /* PBXTargetDependency */ = {
 			isa = PBXTargetDependency;
 			name = debugserver;
@@ -7404,31 +7404,13 @@
 		239504D81BDD451400963CEA /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
-				CLANG_ENABLE_MODULES = YES;
-				CLANG_ENABLE_OBJC_ARC = YES;
-				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
-				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
-				CODE_SIGN_IDENTITY = "-";
-				ENABLE_TESTABILITY = YES;
 				FRAMEWORK_SEARCH_PATHS = (
 					"$(inherited)",
 					"\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"",
 					"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks",
 				);
-				GCC_C_LANGUAGE_STANDARD = gnu99;
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_NO_COMMON_BLOCKS = YES;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"DEBUG=1",
-					"$(inherited)",
-				);
-				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
-				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 				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";
 				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)";
-				MACOSX_DEPLOYMENT_TARGET = 10.11;
-				MTL_ENABLE_DEBUG_INFO = YES;
 				OTHER_CFLAGS = (
 					"-flimit-debug-info",
 					"-Wparentheses",
@@ -7453,38 +7435,19 @@
 					"$(LLDB_GTESTS_LDFLAGS)",
 				);
 				PRODUCT_NAME = "$(TARGET_NAME)";
-				SDKROOT = macosx;
 			};
 			name = Debug;
 		};
 		239504D91BDD451400963CEA /* DebugClang */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
-				CLANG_ENABLE_MODULES = YES;
-				CLANG_ENABLE_OBJC_ARC = YES;
-				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
-				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
-				CODE_SIGN_IDENTITY = "-";
-				ENABLE_TESTABILITY = YES;
 				FRAMEWORK_SEARCH_PATHS = (
 					"$(inherited)",
 					"\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"",
 					"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks",
 				);
-				GCC_C_LANGUAGE_STANDARD = gnu99;
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_NO_COMMON_BLOCKS = YES;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"DEBUG=1",
-					"$(inherited)",
-				);
-				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
-				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 				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";
 				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)";
-				MACOSX_DEPLOYMENT_TARGET = 10.11;
-				MTL_ENABLE_DEBUG_INFO = YES;
 				OTHER_CFLAGS = (
 					"-flimit-debug-info",
 					"-Wparentheses",
@@ -7509,34 +7472,19 @@
 					"$(LLDB_GTESTS_LDFLAGS)",
 				);
 				PRODUCT_NAME = "$(TARGET_NAME)";
-				SDKROOT = macosx;
 			};
 			name = DebugClang;
 		};
 		239504DA1BDD451400963CEA /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
-				CLANG_ENABLE_MODULES = YES;
-				CLANG_ENABLE_OBJC_ARC = YES;
-				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
-				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
-				CODE_SIGN_IDENTITY = "-";
-				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
-				ENABLE_NS_ASSERTIONS = NO;
 				FRAMEWORK_SEARCH_PATHS = (
 					"$(inherited)",
 					"\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"",
 					"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks",
 				);
-				GCC_C_LANGUAGE_STANDARD = gnu99;
-				GCC_NO_COMMON_BLOCKS = YES;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
-				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 				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";
 				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)";
-				MACOSX_DEPLOYMENT_TARGET = 10.11;
-				MTL_ENABLE_DEBUG_INFO = NO;
 				OTHER_CFLAGS = (
 					"-flimit-debug-info",
 					"-Wparentheses",
@@ -7561,34 +7509,19 @@
 					"$(LLDB_GTESTS_LDFLAGS)",
 				);
 				PRODUCT_NAME = "$(TARGET_NAME)";
-				SDKROOT = macosx;
 			};
 			name = Release;
 		};
 		239504DB1BDD451400963CEA /* BuildAndIntegration */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
-				CLANG_ENABLE_MODULES = YES;
-				CLANG_ENABLE_OBJC_ARC = YES;
-				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
-				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
-				CODE_SIGN_IDENTITY = "-";
-				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
-				ENABLE_NS_ASSERTIONS = NO;
 				FRAMEWORK_SEARCH_PATHS = (
 					"$(inherited)",
 					"\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"",
 					"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks",
 				);
-				GCC_C_LANGUAGE_STANDARD = gnu99;
-				GCC_NO_COMMON_BLOCKS = YES;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
-				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 				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";
 				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)";
-				MACOSX_DEPLOYMENT_TARGET = 10.11;
-				MTL_ENABLE_DEBUG_INFO = NO;
 				OTHER_CFLAGS = (
 					"-flimit-debug-info",
 					"-Wparentheses",
@@ -7613,7 +7546,6 @@
 					"$(LLDB_GTESTS_LDFLAGS)",
 				);
 				PRODUCT_NAME = "$(TARGET_NAME)";
-				SDKROOT = macosx;
 			};
 			name = BuildAndIntegration;
 		};

Modified: lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-gtest.xcscheme
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-gtest.xcscheme?rev=251681&r1=251680&r2=251681&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-gtest.xcscheme (original)
+++ lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-gtest.xcscheme Thu Oct 29 21:54:52 2015
@@ -42,7 +42,7 @@
       </AdditionalOptions>
    </TestAction>
    <LaunchAction
-      buildConfiguration = "DebugClang"
+      buildConfiguration = "Debug"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
       launchStyle = "0"

Modified: lldb/trunk/source/Host/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/CMakeLists.txt?rev=251681&r1=251680&r2=251681&view=diff
==============================================================================
--- lldb/trunk/source/Host/CMakeLists.txt (original)
+++ lldb/trunk/source/Host/CMakeLists.txt Thu Oct 29 21:54:52 2015
@@ -170,6 +170,19 @@ if (${get_python_libdir})
   endif()
 endif()
 
+if (${get_python_libdir})
+  # Call a python script to gather the arch-specific libdir for
+  # modules like the lldb module.
+  execute_process(
+    COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../../scripts/get_relative_lib_dir.py
+    RESULT_VARIABLE get_libdir_status
+    OUTPUT_VARIABLE relative_libdir
+    )
+  if (get_libdir_status EQUAL 0)
+    add_definitions(-DLLDB_PYTHON_RELATIVE_LIBDIR="${relative_libdir}")
+  endif()
+endif()
+
 add_lldb_library(lldbHost ${HOST_SOURCES})
 
 if (CMAKE_SYSTEM_NAME MATCHES "NetBSD")

Modified: lldb/trunk/unittests/Editline/EditlineTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Editline/EditlineTest.cpp?rev=251681&r1=251680&r2=251681&view=diff
==============================================================================
--- lldb/trunk/unittests/Editline/EditlineTest.cpp (original)
+++ lldb/trunk/unittests/Editline/EditlineTest.cpp Thu Oct 29 21:54:52 2015
@@ -7,9 +7,362 @@
 //
 //===----------------------------------------------------------------------===//
 
+#ifndef LLDB_DISABLE_LIBEDIT
+
+#define EDITLINE_TEST_DUMP_OUTPUT 0
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include <memory>
+#include <thread>
+
 #include "gtest/gtest.h"
 
-TEST(EditlineTest, BasicTest)
+#include "lldb/Core/Error.h"
+#include "lldb/Core/StringList.h"
+#include "lldb/Host/Editline.h"
+#include "lldb/Host/Pipe.h"
+#include "lldb/Utility/PseudoTerminal.h"
+
+namespace
 {
-    EXPECT_TRUE(true);
+    const size_t TIMEOUT_MILLIS = 5000;
 }
+
+class FilePointer
+{
+public:
+
+    FilePointer () = delete;
+
+    FilePointer (const FilePointer&) = delete;
+
+    FilePointer (FILE *file_p)
+    : _file_p (file_p)
+    {
+    }
+
+    ~FilePointer ()
+    {
+        if (_file_p != nullptr)
+        {
+            const int close_result = fclose (_file_p);
+            EXPECT_EQ(0, close_result);
+        }
+    }
+
+    operator FILE* ()
+    {
+        return _file_p;
+    }
+
+private:
+
+    FILE *_file_p;
+
+};
+
+/**
+ Wraps an Editline class, providing a simple way to feed
+ input (as if from the keyboard) and receive output from Editline.
+ */
+class EditlineAdapter
+{
+public:
+
+    EditlineAdapter ();
+
+    void
+    CloseInput ();
+
+    bool
+    IsValid () const
+    {
+        return _editline_sp.get () != nullptr;
+    }
+
+    lldb_private::Editline&
+    GetEditline ()
+    {
+        return *_editline_sp;
+    }
+
+    bool
+    SendLine (const std::string &line);
+
+    bool
+    SendLines (const std::vector<std::string> &lines);
+
+    bool
+    GetLine (std::string &line, bool &interrupted, size_t timeout_millis);
+
+    bool
+    GetLines (lldb_private::StringList &lines, bool &interrupted, size_t timeout_millis);
+
+    void
+    ConsumeAllOutput ();
+
+private:
+
+    static bool
+    IsInputComplete (
+        lldb_private::Editline * editline,
+        lldb_private::StringList & lines,
+        void * baton);
+
+    std::unique_ptr<lldb_private::Editline> _editline_sp;
+
+    lldb_utility::PseudoTerminal _pty;
+    int _pty_master_fd;
+    int _pty_slave_fd;
+
+    std::unique_ptr<FilePointer> _el_slave_file;
+};
+
+EditlineAdapter::EditlineAdapter () :
+    _editline_sp (),
+    _pty (),
+    _pty_master_fd (-1),
+    _pty_slave_fd (-1),
+    _el_slave_file ()
+{
+    lldb_private::Error error;
+
+    // Open the first master pty available.
+    char error_string[256];
+    error_string[0] = '\0';
+    if (!_pty.OpenFirstAvailableMaster (O_RDWR, error_string, sizeof (error_string)))
+    {
+        fprintf(stderr, "failed to open first available master pty: '%s'\n", error_string);
+        return;
+    }
+
+    // Grab the master fd.  This is a file descriptor we will:
+    // (1) write to when we want to send input to editline.
+    // (2) read from when we want to see what editline sends back.
+    _pty_master_fd = _pty.GetMasterFileDescriptor();
+
+    // Open the corresponding slave pty.
+    if (!_pty.OpenSlave (O_RDWR, error_string, sizeof (error_string)))
+    {
+        fprintf(stderr, "failed to open slave pty: '%s'\n", error_string);
+        return;
+    }
+    _pty_slave_fd = _pty.GetSlaveFileDescriptor();
+
+    _el_slave_file.reset (new FilePointer (fdopen (_pty_slave_fd, "rw")));
+    EXPECT_FALSE (nullptr == *_el_slave_file);
+    if (*_el_slave_file == nullptr)
+        return;
+
+    // Create an Editline instance.
+    _editline_sp.reset (new lldb_private::Editline("gtest editor", *_el_slave_file, *_el_slave_file, *_el_slave_file, false));
+    _editline_sp->SetPrompt ("> ");
+
+    // Hookup our input complete callback.
+    _editline_sp->SetIsInputCompleteCallback(IsInputComplete, this);
+}
+
+void
+EditlineAdapter::CloseInput ()
+{
+    if (_el_slave_file != nullptr)
+        _el_slave_file.reset (nullptr);
+}
+
+bool
+EditlineAdapter::SendLine (const std::string &line)
+{
+    // Ensure we're valid before proceeding.
+    if (!IsValid ())
+        return false;
+
+    // Write the line out to the pipe connected to editline's input.
+    ssize_t input_bytes_written =
+        ::write (_pty_master_fd,
+                 line.c_str(),
+                 line.length() * sizeof (std::string::value_type));
+
+    const char *eoln = "\n";
+    const size_t eoln_length = strlen(eoln);
+    input_bytes_written =
+        ::write (_pty_master_fd,
+                 eoln,
+                 eoln_length * sizeof (char));
+
+    EXPECT_EQ (eoln_length * sizeof (char), input_bytes_written);
+    return eoln_length * sizeof (char) == input_bytes_written;
+}
+
+bool
+EditlineAdapter::SendLines (const std::vector<std::string> &lines)
+{
+    for (auto &line : lines)
+    {
+#if EDITLINE_TEST_DUMP_OUTPUT
+        printf ("<stdin> sending line \"%s\"\n", line.c_str());
+#endif
+        if (!SendLine (line))
+            return false;
+    }
+    return true;
+}
+
+// We ignore the timeout for now.
+bool
+EditlineAdapter::GetLine (std::string &line, bool &interrupted, size_t /* timeout_millis */)
+{
+    // Ensure we're valid before proceeding.
+    if (!IsValid ())
+        return false;
+
+    _editline_sp->GetLine (line, interrupted);
+    return true;
+}
+
+bool
+EditlineAdapter::GetLines (lldb_private::StringList &lines, bool &interrupted, size_t /* timeout_millis */)
+{
+    // Ensure we're valid before proceeding.
+    if (!IsValid ())
+        return false;
+    
+    _editline_sp->GetLines (1, lines, interrupted);
+    return true;
+}
+
+bool
+EditlineAdapter::IsInputComplete (
+        lldb_private::Editline * editline,
+        lldb_private::StringList & lines,
+        void * baton)
+{
+    // We'll call ourselves complete if we've received a balanced set of braces.
+    int start_block_count = 0;
+    int brace_balance = 0;
+
+    for (size_t i = 0; i < lines.GetSize (); ++i)
+    {
+        for (auto ch : lines[i])
+        {
+            if (ch == '{')
+            {
+                ++start_block_count;
+                ++brace_balance;
+            }
+            else if (ch == '}')
+                --brace_balance;
+        }
+    }
+
+    return (start_block_count > 0) && (brace_balance == 0);
+}
+
+void
+EditlineAdapter::ConsumeAllOutput ()
+{
+    FilePointer output_file (fdopen (_pty_master_fd, "r"));
+
+    int ch;
+    while ((ch = fgetc(output_file)) != EOF)
+    {
+#if EDITLINE_TEST_DUMP_OUTPUT
+        char display_str[] = { 0, 0, 0 };
+        switch (ch)
+        {
+            case '\t':
+                display_str[0] = '\\';
+                display_str[1] = 't';
+                break;
+            case '\n':
+                display_str[0] = '\\';
+                display_str[1] = 'n';
+                break;
+            case '\r':
+                display_str[0] = '\\';
+                display_str[1] = 'r';
+                break;
+            default:
+                display_str[0] = ch;
+                break;
+        }
+        printf ("<stdout> 0x%02x (%03d) (%s)\n", ch, ch, display_str);
+        // putc(ch, stdout);
+#endif
+    }
+}
+
+TEST (EditlineTest, EditlineReceivesSingleLineText)
+{
+    setenv ("TERM", "vt100", 1);
+
+    // Create an editline.
+    EditlineAdapter el_adapter;
+    EXPECT_TRUE (el_adapter.IsValid ());
+    if (!el_adapter.IsValid ())
+        return;
+
+    // Dump output.
+    std::thread el_output_thread( [&] { el_adapter.ConsumeAllOutput (); });
+
+    // Send it some text via our virtual keyboard.
+    const std::string input_text ("Hello, world");
+    EXPECT_TRUE (el_adapter.SendLine (input_text));
+
+    // Verify editline sees what we put in.
+    std::string el_reported_line;
+    bool input_interrupted = false;
+    const bool received_line = el_adapter.GetLine (el_reported_line, input_interrupted, TIMEOUT_MILLIS);
+
+    EXPECT_TRUE (received_line);
+    EXPECT_FALSE (input_interrupted);
+    EXPECT_EQ (input_text, el_reported_line);
+
+    el_adapter.CloseInput();
+    el_output_thread.join();
+}
+
+TEST (EditlineTest, EditlineReceivesMultiLineText)
+{
+    setenv ("TERM", "vt100", 1);
+
+    // Create an editline.
+    EditlineAdapter el_adapter;
+    EXPECT_TRUE (el_adapter.IsValid ());
+    if (!el_adapter.IsValid ())
+        return;
+
+    // Stick editline output/error dumpers on separate threads.
+    std::thread el_output_thread( [&] { el_adapter.ConsumeAllOutput (); });
+
+    // Send it some text via our virtual keyboard.
+    std::vector<std::string> input_lines;
+    input_lines.push_back ("int foo()");
+    input_lines.push_back ("{");
+    input_lines.push_back ("printf(\"Hello, world\");");
+    input_lines.push_back ("}");
+    input_lines.push_back ("");
+
+    EXPECT_TRUE (el_adapter.SendLines (input_lines));
+
+    // Verify editline sees what we put in.
+    lldb_private::StringList el_reported_lines;
+    bool input_interrupted = false;
+
+    EXPECT_TRUE (el_adapter.GetLines (el_reported_lines, input_interrupted, TIMEOUT_MILLIS));
+    EXPECT_FALSE (input_interrupted);
+
+    // Without any auto indentation support, our output should directly match our input.
+    EXPECT_EQ (input_lines.size (), el_reported_lines.GetSize ());
+    if (input_lines.size () == el_reported_lines.GetSize ())
+    {
+        for (auto i = 0; i < input_lines.size(); ++i)
+            EXPECT_EQ (input_lines[i], el_reported_lines[i]);
+    }
+
+    el_adapter.CloseInput();
+    el_output_thread.join();
+}
+
+#endif




More information about the lldb-commits mailing list