<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>