summaryrefslogtreecommitdiffstats
path: root/lldb/unittests/Editline/EditlineTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/unittests/Editline/EditlineTest.cpp')
-rw-r--r--lldb/unittests/Editline/EditlineTest.cpp493
1 files changed, 217 insertions, 276 deletions
diff --git a/lldb/unittests/Editline/EditlineTest.cpp b/lldb/unittests/Editline/EditlineTest.cpp
index e2552ffdd3b..55dae525ddc 100644
--- a/lldb/unittests/Editline/EditlineTest.cpp
+++ b/lldb/unittests/Editline/EditlineTest.cpp
@@ -25,348 +25,289 @@
#include "lldb/Host/Pipe.h"
#include "lldb/Utility/PseudoTerminal.h"
-namespace
-{
- const size_t TIMEOUT_MILLIS = 5000;
+namespace {
+const size_t TIMEOUT_MILLIS = 5000;
}
-class FilePointer
-{
+class FilePointer {
public:
+ FilePointer() = delete;
- FilePointer () = delete;
+ FilePointer(const FilePointer &) = delete;
- FilePointer (const FilePointer&) = delete;
+ FilePointer(FILE *file_p) : _file_p(file_p) {}
- 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);
}
+ }
- ~FilePointer ()
- {
- if (_file_p != nullptr)
- {
- const int close_result = fclose (_file_p);
- EXPECT_EQ(0, close_result);
- }
- }
-
- operator FILE* ()
- {
- return _file_p;
- }
+ operator FILE *() { return _file_p; }
private:
-
- FILE *_file_p;
-
+ 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
-{
+class EditlineAdapter {
public:
+ EditlineAdapter();
- EditlineAdapter ();
+ void CloseInput();
- void
- CloseInput ();
+ bool IsValid() const { return _editline_sp.get() != nullptr; }
- bool
- IsValid () const
- {
- return _editline_sp.get () != nullptr;
- }
+ lldb_private::Editline &GetEditline() { return *_editline_sp; }
- lldb_private::Editline&
- GetEditline ()
- {
- return *_editline_sp;
- }
+ bool SendLine(const std::string &line);
- bool
- SendLine (const std::string &line);
+ bool SendLines(const std::vector<std::string> &lines);
- bool
- SendLines (const std::vector<std::string> &lines);
+ bool GetLine(std::string &line, bool &interrupted, size_t timeout_millis);
- bool
- GetLine (std::string &line, bool &interrupted, size_t timeout_millis);
+ bool GetLines(lldb_private::StringList &lines, bool &interrupted,
+ size_t timeout_millis);
- bool
- GetLines (lldb_private::StringList &lines, bool &interrupted, size_t timeout_millis);
-
- void
- ConsumeAllOutput ();
+ void ConsumeAllOutput();
private:
+ static bool IsInputComplete(lldb_private::Editline *editline,
+ lldb_private::StringList &lines, void *baton);
- static bool
- IsInputComplete (
- lldb_private::Editline * editline,
- lldb_private::StringList & lines,
- void * baton);
-
- std::unique_ptr<lldb_private::Editline> _editline_sp;
+ std::unique_ptr<lldb_private::Editline> _editline_sp;
- lldb_utility::PseudoTerminal _pty;
- int _pty_master_fd;
- int _pty_slave_fd;
+ lldb_utility::PseudoTerminal _pty;
+ int _pty_master_fd;
+ int _pty_slave_fd;
- std::unique_ptr<FilePointer> _el_slave_file;
+ 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();
+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);
+}
- _el_slave_file.reset (new FilePointer (fdopen (_pty_slave_fd, "rw")));
- EXPECT_FALSE (nullptr == *_el_slave_file);
- if (*_el_slave_file == nullptr)
- return;
+void EditlineAdapter::CloseInput() {
+ if (_el_slave_file != nullptr)
+ _el_slave_file.reset(nullptr);
+}
- // 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 ("> ");
+bool EditlineAdapter::SendLine(const std::string &line) {
+ // Ensure we're valid before proceeding.
+ if (!IsValid())
+ return false;
- // Hookup our input complete callback.
- _editline_sp->SetIsInputCompleteCallback(IsInputComplete, this);
-}
+ // 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));
-void
-EditlineAdapter::CloseInput ()
-{
- if (_el_slave_file != nullptr)
- _el_slave_file.reset (nullptr);
-}
+ const char *eoln = "\n";
+ const size_t eoln_length = strlen(eoln);
+ input_bytes_written =
+ ::write(_pty_master_fd, eoln, eoln_length * sizeof(char));
-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_NE(-1, input_bytes_written) << strerror(errno);
- EXPECT_EQ (eoln_length * sizeof (char), size_t(input_bytes_written));
- return eoln_length * sizeof (char) == size_t(input_bytes_written);
+ EXPECT_NE(-1, input_bytes_written) << strerror(errno);
+ EXPECT_EQ(eoln_length * sizeof(char), size_t(input_bytes_written));
+ return eoln_length * sizeof(char) == size_t(input_bytes_written);
}
-bool
-EditlineAdapter::SendLines (const std::vector<std::string> &lines)
-{
- for (auto &line : lines)
- {
+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());
+ printf("<stdin> sending line \"%s\"\n", line.c_str());
#endif
- if (!SendLine (line))
- return false;
- }
- return true;
+ 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::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::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;
- }
+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);
+ return (start_block_count > 0) && (brace_balance == 0);
}
-void
-EditlineAdapter::ConsumeAllOutput ()
-{
- FilePointer output_file (fdopen (_pty_master_fd, "r"));
+void EditlineAdapter::ConsumeAllOutput() {
+ FilePointer output_file(fdopen(_pty_master_fd, "r"));
- int ch;
- while ((ch = fgetc(output_file)) != EOF)
- {
+ 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
+ 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
+ }
}
-class EditlineTestFixture : public ::testing::Test
-{
+class EditlineTestFixture : public ::testing::Test {
private:
- EditlineAdapter _el_adapter;
- std::shared_ptr<std::thread> _sp_output_thread;
+ EditlineAdapter _el_adapter;
+ std::shared_ptr<std::thread> _sp_output_thread;
public:
- void SetUp()
- {
- // We need a TERM set properly for editline to work as expected.
- setenv("TERM", "vt100", 1);
-
- // Validate the editline adapter.
- EXPECT_TRUE(_el_adapter.IsValid());
- if (!_el_adapter.IsValid())
- return;
-
- // Dump output.
- _sp_output_thread.reset(new std::thread([&] { _el_adapter.ConsumeAllOutput(); }));
- }
-
- void TearDown()
- {
- _el_adapter.CloseInput();
- if (_sp_output_thread)
- _sp_output_thread->join();
- }
-
- EditlineAdapter &GetEditlineAdapter() { return _el_adapter; }
+ void SetUp() {
+ // We need a TERM set properly for editline to work as expected.
+ setenv("TERM", "vt100", 1);
+
+ // Validate the editline adapter.
+ EXPECT_TRUE(_el_adapter.IsValid());
+ if (!_el_adapter.IsValid())
+ return;
+
+ // Dump output.
+ _sp_output_thread.reset(
+ new std::thread([&] { _el_adapter.ConsumeAllOutput(); }));
+ }
+
+ void TearDown() {
+ _el_adapter.CloseInput();
+ if (_sp_output_thread)
+ _sp_output_thread->join();
+ }
+
+ EditlineAdapter &GetEditlineAdapter() { return _el_adapter; }
};
-TEST_F(EditlineTestFixture, EditlineReceivesSingleLineText)
-{
- // Send it some text via our virtual keyboard.
- const std::string input_text ("Hello, world");
- EXPECT_TRUE(GetEditlineAdapter().SendLine(input_text));
+TEST_F(EditlineTestFixture, EditlineReceivesSingleLineText) {
+ // Send it some text via our virtual keyboard.
+ const std::string input_text("Hello, world");
+ EXPECT_TRUE(GetEditlineAdapter().SendLine(input_text));
- // Verify editline sees what we put in.
- std::string el_reported_line;
- bool input_interrupted = false;
- const bool received_line = GetEditlineAdapter().GetLine(el_reported_line, input_interrupted, TIMEOUT_MILLIS);
+ // Verify editline sees what we put in.
+ std::string el_reported_line;
+ bool input_interrupted = false;
+ const bool received_line = GetEditlineAdapter().GetLine(
+ el_reported_line, input_interrupted, TIMEOUT_MILLIS);
- EXPECT_TRUE (received_line);
- EXPECT_FALSE (input_interrupted);
- EXPECT_EQ (input_text, el_reported_line);
+ EXPECT_TRUE(received_line);
+ EXPECT_FALSE(input_interrupted);
+ EXPECT_EQ(input_text, el_reported_line);
}
-TEST_F(EditlineTestFixture, EditlineReceivesMultiLineText)
-{
- // 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(GetEditlineAdapter().SendLines(input_lines));
-
- // Verify editline sees what we put in.
- lldb_private::StringList el_reported_lines;
- bool input_interrupted = false;
-
- EXPECT_TRUE(GetEditlineAdapter().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 (size_t i = 0; i < input_lines.size(); ++i)
- EXPECT_EQ (input_lines[i], el_reported_lines[i]);
- }
+TEST_F(EditlineTestFixture, EditlineReceivesMultiLineText) {
+ // 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(GetEditlineAdapter().SendLines(input_lines));
+
+ // Verify editline sees what we put in.
+ lldb_private::StringList el_reported_lines;
+ bool input_interrupted = false;
+
+ EXPECT_TRUE(GetEditlineAdapter().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 (size_t i = 0; i < input_lines.size(); ++i)
+ EXPECT_EQ(input_lines[i], el_reported_lines[i]);
+ }
}
#endif
OpenPOWER on IntegriCloud