diff options
7 files changed, 82 insertions, 1 deletions
diff --git a/lldb/include/lldb/Host/File.h b/lldb/include/lldb/Host/File.h index 27f3f405ffd..8be81154cd8 100644 --- a/lldb/include/lldb/Host/File.h +++ b/lldb/include/lldb/Host/File.h @@ -223,6 +223,9 @@ public: Error Close() override; + void + Clear (); + Error Duplicate (const File &rhs); diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/command_script_immediate_output/TestCommandScriptImmediateOutput.py b/lldb/packages/Python/lldbsuite/test/functionalities/command_script_immediate_output/TestCommandScriptImmediateOutput.py new file mode 100644 index 00000000000..6484813f67b --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/command_script_immediate_output/TestCommandScriptImmediateOutput.py @@ -0,0 +1,37 @@ +""" +Test that LLDB correctly allows scripted commands to set an immediate output file +""" + +from __future__ import print_function + + + +import os, time +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.lldbpexpect import * + +class CommandScriptImmediateOutputTestCase (PExpectTest): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + PExpectTest.setUp(self) + + @skipIfRemote # test not remote-ready llvm.org/pr24813 + @expectedFlakeyFreeBSD("llvm.org/pr25172 fails rarely on the buildbot") + @expectedFlakeyLinux("llvm.org/pr25172") + @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows") + def test_command_script_immediate_output (self): + """Test that LLDB correctly allows scripted commands to set an immediate output file.""" + self.launch(timeout=5) + + script = os.path.join(os.getcwd(), 'custom_command.py') + prompt = "(lldb)" + + self.sendline('command script import %s' % script, patterns=[prompt]) + self.sendline('command script add -f custom_command.command_function mycommand', patterns=[prompt]) + self.sendline('mycommand', patterns='this is a test string, just a test string') + self.sendline('command script delete mycommand', patterns=[prompt]) + self.quit(gracefully=False) diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/command_script_immediate_output/custom_command.py b/lldb/packages/Python/lldbsuite/test/functionalities/command_script_immediate_output/custom_command.py new file mode 100644 index 00000000000..a9749196ca7 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/command_script_immediate_output/custom_command.py @@ -0,0 +1,8 @@ +from __future__ import print_function + +import sys + +def command_function(debugger, command, exe_ctx, result, internal_dict): + result.SetImmediateOutputFile(sys.__stdout__) + print('this is a test string, just a test string', file=result) + diff --git a/lldb/scripts/Python/python-typemaps.swig b/lldb/scripts/Python/python-typemaps.swig index 9c4e5cecb36..68e442defd3 100644 --- a/lldb/scripts/Python/python-typemaps.swig +++ b/lldb/scripts/Python/python-typemaps.swig @@ -545,7 +545,9 @@ return nullptr; $1 = file.GetStream(); - } + if ($1) + file.Clear(); + } } %typemap(out) FILE * { diff --git a/lldb/source/Host/common/File.cpp b/lldb/source/Host/common/File.cpp index 71a6149cd61..a862f2cd433 100644 --- a/lldb/source/Host/common/File.cpp +++ b/lldb/source/Host/common/File.cpp @@ -399,6 +399,15 @@ File::Close () return error; } +void +File::Clear () +{ + m_stream = nullptr; + m_descriptor = -1; + m_options = 0; + m_own_stream = false; + m_is_interactive = m_supports_colors = m_is_real_terminal = eLazyBoolCalculate; +} Error File::GetFileSpec (FileSpec &file_spec) const diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp index 23bacc932c0..f0db8a67ff7 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp @@ -23,6 +23,8 @@ #include <stdio.h> +#include "llvm/ADT/StringSwitch.h" + using namespace lldb_private; using namespace lldb; @@ -1156,6 +1158,22 @@ PythonFile::Reset(File &file, const char *mode) #endif } +uint32_t +PythonFile::GetOptionsFromMode(llvm::StringRef mode) +{ + if (mode.empty()) + return 0; + + return llvm::StringSwitch<uint32_t>(mode.str().c_str()) + .Case("r", File::eOpenOptionRead) + .Case("w", File::eOpenOptionWrite) + .Case("a", File::eOpenOptionAppend|File::eOpenOptionCanCreate) + .Case("r+", File::eOpenOptionRead|File::eOpenOptionWrite) + .Case("w+", File::eOpenOptionRead|File::eOpenOptionWrite|File::eOpenOptionCanCreate|File::eOpenOptionTruncate) + .Case("a+", File::eOpenOptionRead|File::eOpenOptionWrite|File::eOpenOptionCanCreate) + .Default(0); +} + bool PythonFile::GetUnderlyingFile(File &file) const { @@ -1166,6 +1184,8 @@ PythonFile::GetUnderlyingFile(File &file) const // We don't own the file descriptor returned by this function, make sure the // File object knows about that. file.SetDescriptor(PyObject_AsFileDescriptor(m_py_obj), false); + PythonString py_mode = GetAttributeValue("mode").AsType<PythonString>(); + file.SetOptions(PythonFile::GetOptionsFromMode(py_mode.GetString())); return file.IsValid(); } diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h index 06264b66c28..6d5a11bd7d9 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h @@ -525,6 +525,8 @@ class PythonFile : public PythonObject void Reset(PyRefType type, PyObject *py_obj) override; void Reset(File &file, const char *mode); + static uint32_t GetOptionsFromMode(llvm::StringRef mode); + bool GetUnderlyingFile(File &file) const; }; |