JDevlieghere updated this revision to Diff 297921.
JDevlieghere added a comment.
Extend test case to show that this works with files sourcing other files.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D89334/new/
https://reviews.llvm.org/D89334
Files:
lldb/include/lldb/Interpreter/CommandInterpreter.h
lldb/include/lldb/Interpreter/ScriptInterpreter.h
lldb/source/Commands/CommandObjectCommands.cpp
lldb/source/Interpreter/CommandInterpreter.cpp
lldb/source/Interpreter/ScriptInterpreter.cpp
lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
lldb/test/Shell/ScriptInterpreter/Python/Inputs/hello.in
lldb/test/Shell/ScriptInterpreter/Python/Inputs/hello.py
lldb/test/Shell/ScriptInterpreter/Python/Inputs/zip.in
lldb/test/Shell/ScriptInterpreter/Python/Inputs/zip.py
lldb/test/Shell/ScriptInterpreter/Python/relative_import.test
Index: lldb/test/Shell/ScriptInterpreter/Python/relative_import.test
===================================================================
--- /dev/null
+++ lldb/test/Shell/ScriptInterpreter/Python/relative_import.test
@@ -0,0 +1,11 @@
+# REQUIRES: python
+
+# RUN: rm -rf %t && mkdir -p %t/foo/bar
+# RUN: cp %S/Inputs/zip.py %t/foo
+# RUN: cp %S/Inputs/zip.in %t/foo
+# RUN: cp %S/Inputs/hello.py %t/foo/bar
+# RUN: cp %S/Inputs/hello.in %t/foo/bar
+# RUN: echo 'command source %t/foo/bar/hello.in' >> %t/foo/zip.in
+# RUN: %lldb --script-language python -o 'command source %t/foo/zip.in' -o 'zip' -o 'hello' 2>&1 | FileCheck %s
+# CHECK: 95126
+# CHECK: Hello, World!
Index: lldb/test/Shell/ScriptInterpreter/Python/Inputs/zip.py
===================================================================
--- /dev/null
+++ lldb/test/Shell/ScriptInterpreter/Python/Inputs/zip.py
@@ -0,0 +1,7 @@
+import lldb
+
+def zip(debugger, command, result, internal_dict):
+ print("95126")
+
+def __lldb_init_module(debugger, internal_dict):
+ debugger.HandleCommand('command script add -f zip.zip zip')
Index: lldb/test/Shell/ScriptInterpreter/Python/Inputs/zip.in
===================================================================
--- /dev/null
+++ lldb/test/Shell/ScriptInterpreter/Python/Inputs/zip.in
@@ -0,0 +1 @@
+command script import zip
Index: lldb/test/Shell/ScriptInterpreter/Python/Inputs/hello.py
===================================================================
--- /dev/null
+++ lldb/test/Shell/ScriptInterpreter/Python/Inputs/hello.py
@@ -0,0 +1,7 @@
+import lldb
+
+def hello(debugger, command, result, internal_dict):
+ print("Hello, World!")
+
+def __lldb_init_module(debugger, internal_dict):
+ debugger.HandleCommand('command script add -f hello.hello hello')
Index: lldb/test/Shell/ScriptInterpreter/Python/Inputs/hello.in
===================================================================
--- /dev/null
+++ lldb/test/Shell/ScriptInterpreter/Python/Inputs/hello.in
@@ -0,0 +1 @@
+command script import hello
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
@@ -231,10 +231,10 @@
bool RunScriptFormatKeyword(const char *impl_function, ValueObject *value,
std::string &output, Status &error) override;
- bool
- LoadScriptingModule(const char *filename, bool init_session,
- lldb_private::Status &error,
- StructuredData::ObjectSP *module_sp = nullptr) override;
+ bool LoadScriptingModule(const char *filename, bool init_session,
+ lldb_private::Status &error,
+ StructuredData::ObjectSP *module_sp = nullptr,
+ FileSpec extra_search_dir = {}) override;
bool IsReservedWord(const char *word) override;
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -2733,7 +2733,7 @@
bool ScriptInterpreterPythonImpl::LoadScriptingModule(
const char *pathname, bool init_session, lldb_private::Status &error,
- StructuredData::ObjectSP *module_sp) {
+ StructuredData::ObjectSP *module_sp, FileSpec extra_search_dir) {
if (!pathname || !pathname[0]) {
error.SetErrorString("invalid pathname");
return false;
@@ -2760,24 +2760,12 @@
fs::file_status st;
std::error_code ec = status(target_file.GetPath(), st);
- if (ec || st.type() == fs::file_type::status_error ||
- st.type() == fs::file_type::type_unknown ||
- st.type() == fs::file_type::file_not_found) {
- // if not a valid file of any sort, check if it might be a filename still
- // dot can't be used but / and \ can, and if either is found, reject
- if (strchr(pathname, '\\') || strchr(pathname, '/')) {
- error.SetErrorString("invalid pathname");
- return false;
- }
- basename = pathname; // not a filename, probably a package of some sort,
- // let it go through
- } else if (is_directory(st) || is_regular_file(st)) {
- if (target_file.GetDirectory().IsEmpty()) {
- error.SetErrorString("invalid directory name");
- return false;
+ auto ExtendSysPath = [this](std::string directory) -> llvm::Error {
+ if (directory.empty()) {
+ return llvm::make_error<llvm::StringError>(
+ "invalid directory name", llvm::inconvertibleErrorCode());
}
- std::string directory = target_file.GetDirectory().GetCString();
replace_all(directory, "\\", "\\\\");
replace_all(directory, "'", "\\'");
@@ -2793,7 +2781,35 @@
.SetSetLLDBGlobals(false))
.Success();
if (!syspath_retval) {
- error.SetErrorString("Python sys.path handling failed");
+ return llvm::make_error<llvm::StringError>(
+ "Python sys.path handling failed", llvm::inconvertibleErrorCode());
+ }
+
+ return llvm::Error::success();
+ };
+
+ if (extra_search_dir) {
+ if (llvm::Error e = ExtendSysPath(extra_search_dir.GetPath())) {
+ error = std::move(e);
+ return false;
+ }
+ }
+
+ if (ec || st.type() == fs::file_type::status_error ||
+ st.type() == fs::file_type::type_unknown ||
+ st.type() == fs::file_type::file_not_found) {
+ // if not a valid file of any sort, check if it might be a filename still
+ // dot can't be used but / and \ can, and if either is found, reject
+ if (strchr(pathname, '\\') || strchr(pathname, '/')) {
+ error.SetErrorString("invalid pathname");
+ return false;
+ }
+ basename = pathname; // not a filename, probably a package of some sort,
+ // let it go through
+ } else if (is_directory(st) || is_regular_file(st)) {
+ if (llvm::Error e =
+ ExtendSysPath(target_file.GetDirectory().GetCString())) {
+ error = std::move(e);
return false;
}
@@ -3229,11 +3245,16 @@
LLDBSwigPyInit();
- // Update the path python uses to search for modules to include the current
- // directory.
-
+ // We need to call this before AddToSysPath as it uses the sys module.
PyRun_SimpleString("import sys");
+
+ // Update the path python uses to search for modules to include the current
+ // directory and the home directory.
AddToSysPath(AddLocation::End, ".");
+ FileSpec home_dir_spec;
+ llvm::SmallString<128> home_dir;
+ if (FileSystem::Instance().GetHomeDirectory(home_dir))
+ AddToSysPath(AddLocation::End, std::string(home_dir));
// Don't denormalize paths when calling file_spec.GetPath(). On platforms
// that use a backslash as the path separator, this will result in executing
Index: lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
+++ lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
@@ -25,10 +25,10 @@
void ExecuteInterpreterLoop() override;
- bool
- LoadScriptingModule(const char *filename, bool init_session,
- lldb_private::Status &error,
- StructuredData::ObjectSP *module_sp = nullptr) override;
+ bool LoadScriptingModule(const char *filename, bool init_session,
+ lldb_private::Status &error,
+ StructuredData::ObjectSP *module_sp = nullptr,
+ FileSpec extra_search_dir = {}) override;
// Static Functions
static void Initialize();
Index: lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
+++ lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
@@ -124,7 +124,7 @@
bool ScriptInterpreterLua::LoadScriptingModule(
const char *filename, bool init_session, lldb_private::Status &error,
- StructuredData::ObjectSP *module_sp) {
+ StructuredData::ObjectSP *module_sp, FileSpec extra_search_dir) {
FileSystem::Instance().Collect(filename);
if (llvm::Error e = m_lua->LoadModule(filename)) {
Index: lldb/source/Interpreter/ScriptInterpreter.cpp
===================================================================
--- lldb/source/Interpreter/ScriptInterpreter.cpp
+++ lldb/source/Interpreter/ScriptInterpreter.cpp
@@ -47,9 +47,11 @@
"This script interpreter does not support watchpoint callbacks.");
}
-bool ScriptInterpreter::LoadScriptingModule(
- const char *filename, bool init_session, lldb_private::Status &error,
- StructuredData::ObjectSP *module_sp) {
+bool ScriptInterpreter::LoadScriptingModule(const char *filename,
+ bool init_session,
+ lldb_private::Status &error,
+ StructuredData::ObjectSP *module_sp,
+ FileSpec extra_search_dir) {
error.SetErrorString(
"This script interpreter does not support importing modules.");
return false;
Index: lldb/source/Interpreter/CommandInterpreter.cpp
===================================================================
--- lldb/source/Interpreter/CommandInterpreter.cpp
+++ lldb/source/Interpreter/CommandInterpreter.cpp
@@ -2554,11 +2554,15 @@
debugger.SetAsyncExecution(false);
m_command_source_depth++;
+ m_command_source_dirs.push_back(cmd_file.CopyByRemovingLastPathComponent());
debugger.RunIOHandlerSync(io_handler_sp);
if (!m_command_source_flags.empty())
m_command_source_flags.pop_back();
+
+ m_command_source_dirs.pop_back();
m_command_source_depth--;
+
result.SetStatus(eReturnStatusSuccessFinishNoResult);
debugger.SetAsyncExecution(old_async_execution);
}
@@ -2964,6 +2968,12 @@
return true;
}
+FileSpec CommandInterpreter::GetCurrentSourceDir() {
+ if (m_command_source_dirs.empty())
+ return {};
+ return m_command_source_dirs.back();
+}
+
void CommandInterpreter::GetLLDBCommandsFromIOHandler(
const char *prompt, IOHandlerDelegate &delegate, void *baton) {
Debugger &debugger = GetDebugger();
Index: lldb/source/Commands/CommandObjectCommands.cpp
===================================================================
--- lldb/source/Commands/CommandObjectCommands.cpp
+++ lldb/source/Commands/CommandObjectCommands.cpp
@@ -1294,6 +1294,9 @@
return false;
}
+ FileSpec source_dir =
+ GetDebugger().GetCommandInterpreter().GetCurrentSourceDir();
+
for (auto &entry : command.entries()) {
Status error;
@@ -1308,7 +1311,7 @@
// more)
m_exe_ctx.Clear();
if (GetDebugger().GetScriptInterpreter()->LoadScriptingModule(
- entry.c_str(), init_session, error)) {
+ entry.c_str(), init_session, error, nullptr, source_dir)) {
result.SetStatus(eReturnStatusSuccessFinishNoResult);
} else {
result.AppendErrorWithFormat("module importing failed: %s",
Index: lldb/include/lldb/Interpreter/ScriptInterpreter.h
===================================================================
--- lldb/include/lldb/Interpreter/ScriptInterpreter.h
+++ lldb/include/lldb/Interpreter/ScriptInterpreter.h
@@ -507,7 +507,8 @@
virtual bool
LoadScriptingModule(const char *filename, bool init_session,
lldb_private::Status &error,
- StructuredData::ObjectSP *module_sp = nullptr);
+ StructuredData::ObjectSP *module_sp = nullptr,
+ FileSpec extra_search_dir = {});
virtual bool IsReservedWord(const char *word) { return false; }
Index: lldb/include/lldb/Interpreter/CommandInterpreter.h
===================================================================
--- lldb/include/lldb/Interpreter/CommandInterpreter.h
+++ lldb/include/lldb/Interpreter/CommandInterpreter.h
@@ -551,6 +551,8 @@
bool SaveTranscript(CommandReturnObject &result,
llvm::Optional<std::string> output_file = llvm::None);
+ FileSpec GetCurrentSourceDir();
+
protected:
friend class Debugger;
@@ -637,7 +639,13 @@
ChildrenTruncatedWarningStatus m_truncation_warning; // Whether we truncated
// children and whether
// the user has been told
+
+ // FIXME: Stop using this to control adding to the history and then replace
+ // this with m_command_source_dirs.size().
uint32_t m_command_source_depth;
+ /// A stack of directory paths. When not empty, the last one is the directory
+ /// of the file that's currently sourced.
+ std::vector<FileSpec> m_command_source_dirs;
std::vector<uint32_t> m_command_source_flags;
CommandInterpreterRunResult m_result;
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits