[Lldb-commits] [lldb] r142283 - in /lldb/trunk: include/lldb/Host/ include/lldb/Interpreter/ scripts/Python/ source/API/ source/Commands/ source/Host/common/ source/Interpreter/ test/functionalities/command_script/import/ test/functionalities/command_script/import/bar/ test/functionalities/command_script/import/foo/ test/functionalities/command_script/import/foo/bar/
Enrico Granata
granata.enrico at gmail.com
Mon Oct 17 14:45:27 PDT 2011
Author: enrico
Date: Mon Oct 17 16:45:27 2011
New Revision: 142283
URL: http://llvm.org/viewvc/llvm-project?rev=142283&view=rev
Log:
this patch introduces a new command script import command which takes as input a filename for a Python script and imports the module contained in that file. the containing directory is added to the Python path such that dependencies are honored. also, the module may contain an __lldb_init_module(debugger,dict) function, which gets called after importing, and which can somehow initialize the module's interaction with lldb
Added:
lldb/trunk/test/functionalities/command_script/import/
lldb/trunk/test/functionalities/command_script/import/Makefile
lldb/trunk/test/functionalities/command_script/import/TestImport.py
lldb/trunk/test/functionalities/command_script/import/bar/
lldb/trunk/test/functionalities/command_script/import/bar/bar.py
lldb/trunk/test/functionalities/command_script/import/bar/barutil.py
lldb/trunk/test/functionalities/command_script/import/dummymodule.py
lldb/trunk/test/functionalities/command_script/import/foo/
lldb/trunk/test/functionalities/command_script/import/foo/bar/
lldb/trunk/test/functionalities/command_script/import/foo/bar/foobar.py
lldb/trunk/test/functionalities/command_script/import/foo/foo.py
lldb/trunk/test/functionalities/command_script/import/foo/foo2.py
lldb/trunk/test/functionalities/command_script/import/main.c
Modified:
lldb/trunk/include/lldb/Host/FileSpec.h
lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
lldb/trunk/scripts/Python/python-wrapper.swig
lldb/trunk/source/API/SBCommandInterpreter.cpp
lldb/trunk/source/Commands/CommandObjectCommands.cpp
lldb/trunk/source/Host/common/FileSpec.cpp
lldb/trunk/source/Interpreter/ScriptInterpreter.cpp
lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
Modified: lldb/trunk/include/lldb/Host/FileSpec.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/FileSpec.h?rev=142283&r1=142282&r2=142283&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/FileSpec.h (original)
+++ lldb/trunk/include/lldb/Host/FileSpec.h Mon Oct 17 16:45:27 2011
@@ -357,6 +357,34 @@
size_t
GetPath (char *path, size_t max_path_length) const;
+ //------------------------------------------------------------------
+ /// Extract the extension of the file.
+ ///
+ /// Returns a ConstString that represents the extension of the filename
+ /// for this FileSpec object. If this object does not represent a file,
+ /// or the filename has no extension, ConstString(NULL) is returned.
+ /// The dot ('.') character is not returned as part of the extension
+ ///
+ /// @return
+ /// Returns the extension of the file as a ConstString object.
+ //------------------------------------------------------------------
+ ConstString
+ GetFileNameExtension () const;
+
+ //------------------------------------------------------------------
+ /// Return the filename without the extension part
+ ///
+ /// Returns a ConstString that represents the filename of this object
+ /// without the extension part (e.g. for a file named "foo.bar", "foo"
+ /// is returned)
+ ///
+ /// @return
+ /// Returns the filename without extension
+ /// as a ConstString object.
+ //------------------------------------------------------------------
+ ConstString
+ GetFileNameStrippingExtension () const;
+
FileType
GetFileType () const;
Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h?rev=142283&r1=142282&r2=142283&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h Mon Oct 17 16:45:27 2011
@@ -11,7 +11,10 @@
#define liblldb_ScriptInterpreter_h_
#include "lldb/lldb-private.h"
+
#include "lldb/Core/Broadcaster.h"
+#include "lldb/Core/Error.h"
+
#include "lldb/Utility/PseudoTerminal.h"
@@ -48,24 +51,28 @@
const char* args,
std::string& err_msg,
lldb_private::CommandReturnObject& cmd_retobj);
+
+ typedef bool (*SWIGPythonCallModuleInit) (const std::string python_module_name,
+ const char *session_dictionary_name,
+ lldb::DebuggerSP& debugger);
typedef enum
{
- eCharPtr,
- eBool,
- eShortInt,
- eShortIntUnsigned,
- eInt,
- eIntUnsigned,
- eLongInt,
- eLongIntUnsigned,
- eLongLong,
- eLongLongUnsigned,
- eFloat,
- eDouble,
- eChar,
- eCharStrOrNone
- } ReturnType;
+ eScriptReturnTypeCharPtr,
+ eScriptReturnTypeBool,
+ eScriptReturnTypeShortInt,
+ eScriptReturnTypeShortIntUnsigned,
+ eScriptReturnTypeInt,
+ eScriptReturnTypeIntUnsigned,
+ eScriptReturnTypeLongInt,
+ eScriptReturnTypeLongIntUnsigned,
+ eScriptReturnTypeLongLong,
+ eScriptReturnTypeLongLongUnsigned,
+ eScriptReturnTypeFloat,
+ eScriptReturnTypeDouble,
+ eScriptReturnTypeChar,
+ eScriptReturnTypeCharStrOrNone
+ } ScriptReturnType;
ScriptInterpreter (CommandInterpreter &interpreter, lldb::ScriptLanguage script_lang);
@@ -79,7 +86,7 @@
ExecuteInterpreterLoop () = 0;
virtual bool
- ExecuteOneLineWithReturn (const char *in_string, ReturnType return_type, void *ret_value)
+ ExecuteOneLineWithReturn (const char *in_string, ScriptReturnType return_type, void *ret_value)
{
return true;
}
@@ -176,20 +183,28 @@
}
virtual bool
- RunScriptBasedCommand(const char* impl_function,
- const char* args,
- lldb_private::CommandReturnObject& cmd_retobj,
- Error& error)
+ RunScriptBasedCommand (const char* impl_function,
+ const char* args,
+ lldb_private::CommandReturnObject& cmd_retobj,
+ Error& error)
{
return false;
}
virtual std::string
- GetDocumentationForItem(const char* item)
+ GetDocumentationForItem (const char* item)
{
return std::string("");
}
+ virtual bool
+ LoadScriptingModule (const char* filename,
+ lldb_private::Error& error)
+ {
+ error.SetErrorString("loading unimplemented");
+ return false;
+ }
+
const char *
GetScriptInterpreterPtyName ();
@@ -212,7 +227,8 @@
SWIGPythonGetIndexOfChildWithName python_swig_get_index_child,
SWIGPythonCastPyObjectToSBValue python_swig_cast_to_sbvalue,
SWIGPythonUpdateSynthProviderInstance python_swig_update_provider,
- SWIGPythonCallCommand python_swig_call_command);
+ SWIGPythonCallCommand python_swig_call_command,
+ SWIGPythonCallModuleInit python_swig_call_mod_init);
static void
TerminateInterpreter ();
Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h?rev=142283&r1=142282&r2=142283&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h Mon Oct 17 16:45:27 2011
@@ -40,7 +40,7 @@
bool
ExecuteOneLineWithReturn (const char *in_string,
- ScriptInterpreter::ReturnType return_type,
+ ScriptInterpreter::ScriptReturnType return_type,
void *ret_value);
bool
@@ -108,7 +108,11 @@
lldb::ValueObjectSP valobj);
virtual std::string
- GetDocumentationForItem(const char* item);
+ GetDocumentationForItem (const char* item);
+
+ virtual bool
+ LoadScriptingModule (const char* filename,
+ lldb_private::Error& error);
void
CollectDataForBreakpointCommandCallback (BreakpointOptions *bp_options,
@@ -141,7 +145,8 @@
SWIGPythonGetIndexOfChildWithName python_swig_get_index_child,
SWIGPythonCastPyObjectToSBValue python_swig_cast_to_sbvalue,
SWIGPythonUpdateSynthProviderInstance python_swig_update_provider,
- SWIGPythonCallCommand python_swig_call_command);
+ SWIGPythonCallCommand python_swig_call_command,
+ SWIGPythonCallModuleInit python_swig_call_mod_init);
protected:
Modified: lldb/trunk/scripts/Python/python-wrapper.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/python-wrapper.swig?rev=142283&r1=142282&r2=142283&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/python-wrapper.swig (original)
+++ lldb/trunk/scripts/Python/python-wrapper.swig Mon Oct 17 16:45:27 2011
@@ -676,7 +676,89 @@
PyErr_Print();
PyErr_Clear ();
}
-return retval;
+ return retval;
+}
+
+SWIGEXPORT bool
+LLDBSwigPythonCallModuleInit
+(
+ const std::string python_module_name,
+ const char *session_dictionary_name,
+ lldb::DebuggerSP& debugger
+)
+{
+
+ lldb::SBDebugger debugger_sb(debugger);
+
+ bool retval = false;
+
+ PyObject *DebuggerObj_PyObj = SWIG_NewPointerObj((void *) &debugger_sb, SWIGTYPE_p_lldb__SBDebugger, 0);
+
+ if (DebuggerObj_PyObj == NULL)
+ return retval;
+
+ if (!(python_module_name.length()) || !session_dictionary_name)
+ return retval;
+
+ PyObject *session_dict, *pfunc;
+ PyObject *pargs, *pvalue;
+
+ session_dict = FindSessionDictionary (session_dictionary_name);
+
+ std::string python_function_name_string = python_module_name + (".__lldb_init_module");
+ const char* python_function_name = python_function_name_string.c_str();
+
+ if (session_dict != NULL)
+ {
+ pfunc = ResolvePythonName (python_function_name, session_dict);
+
+ if (PyErr_Occurred()) // this might not exist.. let's make sure we handle that
+ {
+ PyErr_Clear();
+ return true;
+ }
+
+ if (pfunc == NULL)
+ return true;
+ else
+ {
+ // Set up the arguments and call the function.
+
+ if (PyCallable_Check (pfunc))
+ {
+ pargs = PyTuple_New (2);
+ if (pargs == NULL)
+ {
+ if (PyErr_Occurred())
+ PyErr_Clear();
+ return retval;
+ }
+
+ PyTuple_SetItem (pargs, 0, DebuggerObj_PyObj); // This "steals" a reference to DebuggerObj_PyObj
+ PyTuple_SetItem (pargs, 1, session_dict); // This "steals" a reference to session_dict
+ pvalue = PyObject_CallObject (pfunc, pargs);
+ Py_DECREF (pargs);
+
+ if (PyErr_Occurred ())
+ {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+ else
+ {
+ retval = true;
+ Py_XDECREF (pvalue);
+ }
+ Py_INCREF (session_dict);
+ }
+ else if (PyErr_Occurred())
+ {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+ }
+ }
+ return retval;
}
%}
Modified: lldb/trunk/source/API/SBCommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBCommandInterpreter.cpp?rev=142283&r1=142282&r2=142283&view=diff
==============================================================================
--- lldb/trunk/source/API/SBCommandInterpreter.cpp (original)
+++ lldb/trunk/source/API/SBCommandInterpreter.cpp Mon Oct 17 16:45:27 2011
@@ -358,6 +358,13 @@
lldb_private::CommandReturnObject& cmd_retobj
);
+extern "C" bool LLDBSwigPythonCallModuleInit
+(
+ const std::string python_module_name,
+ const char *session_dictionary_name,
+ lldb::DebuggerSP& debugger
+);
+
extern "C" void init_lldb(void);
@@ -377,6 +384,7 @@
LLDBSwigPython_GetIndexOfChildWithName,
LLDBSWIGPython_CastPyObjectToSBValue,
LLDBSwigPython_UpdateSynthProviderInstance,
- LLDBSwigPythonCallCommand);
+ LLDBSwigPythonCallCommand,
+ LLDBSwigPythonCallModuleInit);
}
}
Modified: lldb/trunk/source/Commands/CommandObjectCommands.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectCommands.cpp?rev=142283&r1=142282&r2=142283&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectCommands.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectCommands.cpp Mon Oct 17 16:45:27 2011
@@ -1220,6 +1220,78 @@
};
+//-------------------------------------------------------------------------
+// CommandObjectCommandsScriptImport
+//-------------------------------------------------------------------------
+
+class CommandObjectCommandsScriptImport : public CommandObject
+{
+public:
+ CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
+ CommandObject (interpreter,
+ "command script import",
+ "Import a scripting module in LLDB.",
+ NULL)
+ {
+ CommandArgumentEntry arg1;
+ CommandArgumentData cmd_arg;
+
+ // Define the first (and only) variant of this arg.
+ cmd_arg.arg_type = eArgTypePath;
+ cmd_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the argument entry.
+ arg1.push_back (cmd_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back (arg1);
+ }
+
+ ~CommandObjectCommandsScriptImport ()
+ {
+ }
+
+ bool
+ Execute
+ (
+ Args& args,
+ CommandReturnObject &result
+ )
+ {
+
+ if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
+ {
+ result.AppendError ("only scripting language supported for module importing is currently Python");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ size_t argc = args.GetArgumentCount();
+
+ if (argc != 1)
+ {
+ result.AppendError ("'command script import' requires one argument");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ std::string path = args.GetArgumentAtIndex(0);
+ Error error;
+
+ if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
+ error))
+ {
+ result.SetStatus (eReturnStatusSuccessFinishNoResult);
+ }
+ else
+ {
+ result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
+ result.SetStatus (eReturnStatusFailed);
+ }
+
+ return result.Succeeded();
+ }
+};
//-------------------------------------------------------------------------
// CommandObjectCommandsScriptAdd
@@ -1684,6 +1756,7 @@
LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
+ LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
}
~CommandObjectMultiwordCommandsScript ()
Modified: lldb/trunk/source/Host/common/FileSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/FileSpec.cpp?rev=142283&r1=142282&r2=142283&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/FileSpec.cpp (original)
+++ lldb/trunk/source/Host/common/FileSpec.cpp Mon Oct 17 16:45:27 2011
@@ -699,10 +699,39 @@
return ::snprintf (path, path_max_len, "%s", filename);
}
}
- path[0] = '\0';
+ if (path)
+ path[0] = '\0';
return 0;
}
+ConstString
+FileSpec::GetFileNameExtension () const
+{
+ const char *filename = m_filename.GetCString();
+ if (filename == NULL)
+ return ConstString();
+
+ char* dot_pos = strrchr(filename, '.');
+ if (dot_pos == NULL)
+ return ConstString();
+
+ return ConstString(dot_pos+1);
+}
+
+ConstString
+FileSpec::GetFileNameStrippingExtension () const
+{
+ const char *filename = m_filename.GetCString();
+ if (filename == NULL)
+ return ConstString();
+
+ char* dot_pos = strrchr(filename, '.');
+ if (dot_pos == NULL)
+ return m_filename;
+
+ return ConstString(filename, dot_pos-filename);
+}
+
//------------------------------------------------------------------
// Returns a shared pointer to a data buffer that contains all or
// part of the contents of a file. The data is memory mapped and
Modified: lldb/trunk/source/Interpreter/ScriptInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreter.cpp?rev=142283&r1=142282&r2=142283&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreter.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreter.cpp Mon Oct 17 16:45:27 2011
@@ -100,7 +100,8 @@
SWIGPythonGetIndexOfChildWithName python_swig_get_index_child,
SWIGPythonCastPyObjectToSBValue python_swig_cast_to_sbvalue,
SWIGPythonUpdateSynthProviderInstance python_swig_update_provider,
- SWIGPythonCallCommand python_swig_call_command)
+ SWIGPythonCallCommand python_swig_call_command,
+ SWIGPythonCallModuleInit python_swig_call_mod_init)
{
ScriptInterpreterPython::InitializeInterpreter (python_swig_init_callback,
python_swig_breakpoint_callback,
@@ -111,7 +112,8 @@
python_swig_get_index_child,
python_swig_cast_to_sbvalue,
python_swig_update_provider,
- python_swig_call_command);
+ python_swig_call_command,
+ python_swig_call_mod_init);
}
void
Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=142283&r1=142282&r2=142283&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Mon Oct 17 16:45:27 2011
@@ -42,6 +42,7 @@
static ScriptInterpreter::SWIGPythonCastPyObjectToSBValue g_swig_cast_to_sbvalue = NULL;
static ScriptInterpreter::SWIGPythonUpdateSynthProviderInstance g_swig_update_provider = NULL;
static ScriptInterpreter::SWIGPythonCallCommand g_swig_call_command = NULL;
+static ScriptInterpreter::SWIGPythonCallModuleInit g_swig_call_module_init = NULL;
static int
_check_and_flush (FILE *stream)
@@ -199,6 +200,10 @@
PyRun_SimpleString (run_string.GetData());
run_string.Clear();
+ run_string.Printf ("run_one_line (%s, 'import os')", m_dictionary_name.c_str());
+ PyRun_SimpleString (run_string.GetData());
+
+ run_string.Clear();
run_string.Printf ("run_one_line (%s, 'lldb.debugger_unique_id = %d')", m_dictionary_name.c_str(),
interpreter.GetDebugger().GetID());
PyRun_SimpleString (run_string.GetData());
@@ -702,7 +707,7 @@
bool
ScriptInterpreterPython::ExecuteOneLineWithReturn (const char *in_string,
- ScriptInterpreter::ReturnType return_type,
+ ScriptInterpreter::ScriptReturnType return_type,
void *ret_value)
{
@@ -783,85 +788,85 @@
{
switch (return_type)
{
- case eCharPtr: // "char *"
+ case eScriptReturnTypeCharPtr: // "char *"
{
const char format[3] = "s#";
success = PyArg_Parse (py_return, format, (char **) ret_value);
break;
}
- case eCharStrOrNone: // char* or NULL if py_return == Py_None
+ case eScriptReturnTypeCharStrOrNone: // char* or NULL if py_return == Py_None
{
const char format[3] = "z";
success = PyArg_Parse (py_return, format, (char **) ret_value);
break;
}
- case eBool:
+ case eScriptReturnTypeBool:
{
const char format[2] = "b";
success = PyArg_Parse (py_return, format, (bool *) ret_value);
break;
}
- case eShortInt:
+ case eScriptReturnTypeShortInt:
{
const char format[2] = "h";
success = PyArg_Parse (py_return, format, (short *) ret_value);
break;
}
- case eShortIntUnsigned:
+ case eScriptReturnTypeShortIntUnsigned:
{
const char format[2] = "H";
success = PyArg_Parse (py_return, format, (unsigned short *) ret_value);
break;
}
- case eInt:
+ case eScriptReturnTypeInt:
{
const char format[2] = "i";
success = PyArg_Parse (py_return, format, (int *) ret_value);
break;
}
- case eIntUnsigned:
+ case eScriptReturnTypeIntUnsigned:
{
const char format[2] = "I";
success = PyArg_Parse (py_return, format, (unsigned int *) ret_value);
break;
}
- case eLongInt:
+ case eScriptReturnTypeLongInt:
{
const char format[2] = "l";
success = PyArg_Parse (py_return, format, (long *) ret_value);
break;
}
- case eLongIntUnsigned:
+ case eScriptReturnTypeLongIntUnsigned:
{
const char format[2] = "k";
success = PyArg_Parse (py_return, format, (unsigned long *) ret_value);
break;
}
- case eLongLong:
+ case eScriptReturnTypeLongLong:
{
const char format[2] = "L";
success = PyArg_Parse (py_return, format, (long long *) ret_value);
break;
}
- case eLongLongUnsigned:
+ case eScriptReturnTypeLongLongUnsigned:
{
const char format[2] = "K";
success = PyArg_Parse (py_return, format, (unsigned long long *) ret_value);
break;
}
- case eFloat:
+ case eScriptReturnTypeFloat:
{
const char format[2] = "f";
success = PyArg_Parse (py_return, format, (float *) ret_value);
break;
}
- case eDouble:
+ case eScriptReturnTypeDouble:
{
const char format[2] = "d";
success = PyArg_Parse (py_return, format, (double *) ret_value);
break;
}
- case eChar:
+ case eScriptReturnTypeChar:
{
const char format[2] = "c";
success = PyArg_Parse (py_return, format, (char *) ret_value);
@@ -1825,6 +1830,98 @@
}
bool
+ScriptInterpreterPython::LoadScriptingModule (const char* pathname,
+ lldb_private::Error& error)
+{
+ if (!pathname || !pathname[0])
+ {
+ error.SetErrorString("invalid pathname");
+ return false;
+ }
+
+ if (!g_swig_call_module_init)
+ {
+ error.SetErrorString("internal helper function missing");
+ return false;
+ }
+
+ ScriptInterpreterPython *python_interpreter = this;
+
+ lldb::DebuggerSP debugger_sp = m_interpreter.GetDebugger().GetSP();
+
+ FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
+
+ {
+ Locker py_lock(python_interpreter, tmp_fh);
+
+ FileSpec target_file(pathname, true);
+
+ // TODO: would we want to reject any other value?
+ if (target_file.GetFileType() == FileSpec::eFileTypeInvalid ||
+ target_file.GetFileType() == FileSpec::eFileTypeUnknown)
+ {
+ error.SetErrorString("invalid pathname");
+ return false;
+ }
+
+ const char* directory = target_file.GetDirectory().GetCString();
+ std::string basename(target_file.GetFilename().GetCString());
+
+ // now make sure that Python has "directory" in the search path
+ StreamString command_stream;
+ command_stream.Printf("if not (sys.path.__contains__('%s')):\n sys.path.append('%s');\n\n",
+ directory,
+ directory);
+ bool syspath_retval = python_interpreter->ExecuteMultipleLines(command_stream.GetData());
+ if (!syspath_retval)
+ {
+ error.SetErrorString("Python sys.path handling failed");
+ return false;
+ }
+
+ // strip .py or .pyc extension
+ ConstString extension = target_file.GetFileNameExtension();
+ if (::strcmp(extension.GetCString(), "py") == 0)
+ basename.resize(basename.length()-3);
+ else if(::strcmp(extension.GetCString(), "pyc") == 0)
+ basename.resize(basename.length()-4);
+
+ // check if the module is already import-ed
+ command_stream.Clear();
+ command_stream.Printf("sys.getrefcount(%s)",basename.c_str());
+ int refcount = 0;
+ // this call will fail if the module does not exist (because the parameter to it is not a string
+ // but an actual Python module object, which is non-existant if the module was not imported before)
+ if (python_interpreter->ExecuteOneLineWithReturn(command_stream.GetData(),
+ ScriptInterpreterPython::eScriptReturnTypeInt, &refcount) && refcount > 0)
+ {
+ error.SetErrorString("module already imported");
+ return false;
+ }
+
+ // now actually do the import
+ command_stream.Clear();
+ command_stream.Printf("import %s",basename.c_str());
+ bool import_retval = python_interpreter->ExecuteOneLine(command_stream.GetData(), NULL);
+ if (!import_retval)
+ {
+ error.SetErrorString("Python import statement failed");
+ return false;
+ }
+
+ // call __lldb_module_init(debugger,dict)
+ if (!g_swig_call_module_init (basename,
+ python_interpreter->m_dictionary_name.c_str(),
+ debugger_sp))
+ {
+ error.SetErrorString("calling __lldb_module_init failed");
+ return false;
+ }
+ return true;
+ }
+}
+
+bool
ScriptInterpreterPython::RunScriptBasedCommand(const char* impl_function,
const char* args,
lldb_private::CommandReturnObject& cmd_retobj,
@@ -1886,7 +1983,7 @@
char* result_ptr = NULL; // Python is going to point this to valid data if ExecuteOneLineWithReturn returns successfully
if (ExecuteOneLineWithReturn (command.c_str(),
- ScriptInterpreter::eCharStrOrNone,
+ ScriptInterpreter::eScriptReturnTypeCharStrOrNone,
&result_ptr) && result_ptr)
{
return std::string(result_ptr);
@@ -1905,7 +2002,8 @@
SWIGPythonGetIndexOfChildWithName python_swig_get_index_child,
SWIGPythonCastPyObjectToSBValue python_swig_cast_to_sbvalue,
SWIGPythonUpdateSynthProviderInstance python_swig_update_provider,
- SWIGPythonCallCommand python_swig_call_command)
+ SWIGPythonCallCommand python_swig_call_command,
+ SWIGPythonCallModuleInit python_swig_call_mod_init)
{
g_swig_init_callback = python_swig_init_callback;
g_swig_breakpoint_callback = python_swig_breakpoint_callback;
@@ -1917,6 +2015,7 @@
g_swig_cast_to_sbvalue = python_swig_cast_to_sbvalue;
g_swig_update_provider = python_swig_update_provider;
g_swig_call_command = python_swig_call_command;
+ g_swig_call_module_init = python_swig_call_mod_init;
}
void
Added: lldb/trunk/test/functionalities/command_script/import/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/command_script/import/Makefile?rev=142283&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/command_script/import/Makefile (added)
+++ lldb/trunk/test/functionalities/command_script/import/Makefile Mon Oct 17 16:45:27 2011
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+EXE := hello_world
+
+include $(LEVEL)/Makefile.rules
Added: lldb/trunk/test/functionalities/command_script/import/TestImport.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/command_script/import/TestImport.py?rev=142283&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/command_script/import/TestImport.py (added)
+++ lldb/trunk/test/functionalities/command_script/import/TestImport.py Mon Oct 17 16:45:27 2011
@@ -0,0 +1,71 @@
+"""Test custom import command to import files by path."""
+
+import os, sys, time
+import unittest2
+import lldb
+from lldbtest import *
+
+class ImportTestCase(TestBase):
+
+ mydir = os.path.join("functionalities", "command_script", "import")
+
+ @python_api_test
+ def test_import_command(self):
+ """Import some Python scripts by path and test them"""
+ self.run_test()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+
+ def run_test(self):
+ """Import some Python scripts by path and test them."""
+
+ # This is the function to remove the custom commands in order to have a
+ # clean slate for the next test case.
+ def cleanup():
+ self.runCmd('command script delete foo2cmd', check=False)
+ self.runCmd('command script delete foocmd', check=False)
+ self.runCmd('command script delete foobarcmd', check=False)
+ self.runCmd('command script delete barcmd', check=False)
+ self.runCmd('command script delete barothercmd', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.runCmd("command script import ./foo/foo.py")
+ self.runCmd("command script import ./foo/foo2.py")
+ self.runCmd("command script import ./foo/bar/foobar.py")
+ self.runCmd("command script import ./bar/bar.py")
+
+ self.expect("command script import ./nosuchfile.py",
+ error=True, startstr='error: module importing failed')
+ self.expect("command script import ./nosuchfolder/",
+ error=True, startstr='error: module importing failed')
+ self.expect("command script import ./foo/foo.py",
+ error=True, startstr='error: module importing failed')
+
+ self.runCmd("script import dummymodule")
+ self.expect("command script import ./dummymodule.py",
+ error=True, startstr='error: module importing failed')
+
+ self.runCmd("command script add -f foo.foo_function foocmd")
+ self.runCmd("command script add -f foobar.foo_function foobarcmd")
+ self.runCmd("command script add -f bar.bar_function barcmd")
+ self.expect("foocmd hello",
+ substrs = ['foo says', 'hello'])
+ self.expect("foo2cmd hello",
+ substrs = ['foo2 says', 'hello'])
+ self.expect("barcmd hello",
+ substrs = ['barutil says', 'bar told me', 'hello'])
+ self.expect("barothercmd hello",
+ substrs = ['barutil says', 'bar told me', 'hello'])
+ self.expect("foobarcmd hello",
+ substrs = ['foobar says', 'hello'])
+
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Added: lldb/trunk/test/functionalities/command_script/import/bar/bar.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/command_script/import/bar/bar.py?rev=142283&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/command_script/import/bar/bar.py (added)
+++ lldb/trunk/test/functionalities/command_script/import/bar/bar.py Mon Oct 17 16:45:27 2011
@@ -0,0 +1,10 @@
+def bar_function(debugger, args, result, dict):
+ global UtilityModule
+ result.Printf(UtilityModule.barutil_function("bar told me " + args))
+ return None
+
+def __lldb_init_module(debugger, session_dict):
+ global UtilityModule
+ UtilityModule = __import__("barutil")
+ debugger.HandleCommand("command script add -f bar.bar_function barothercmd")
+ return None
\ No newline at end of file
Added: lldb/trunk/test/functionalities/command_script/import/bar/barutil.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/command_script/import/bar/barutil.py?rev=142283&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/command_script/import/bar/barutil.py (added)
+++ lldb/trunk/test/functionalities/command_script/import/bar/barutil.py Mon Oct 17 16:45:27 2011
@@ -0,0 +1,2 @@
+def barutil_function(x):
+ return "barutil says: " + x
Added: lldb/trunk/test/functionalities/command_script/import/dummymodule.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/command_script/import/dummymodule.py?rev=142283&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/command_script/import/dummymodule.py (added)
+++ lldb/trunk/test/functionalities/command_script/import/dummymodule.py Mon Oct 17 16:45:27 2011
@@ -0,0 +1,2 @@
+def no_useful_code(foo):
+ return foo
Added: lldb/trunk/test/functionalities/command_script/import/foo/bar/foobar.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/command_script/import/foo/bar/foobar.py?rev=142283&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/command_script/import/foo/bar/foobar.py (added)
+++ lldb/trunk/test/functionalities/command_script/import/foo/bar/foobar.py Mon Oct 17 16:45:27 2011
@@ -0,0 +1,3 @@
+def foo_function(debugger, args, result, dict):
+ result.Printf("foobar says " + args)
+ return None
Added: lldb/trunk/test/functionalities/command_script/import/foo/foo.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/command_script/import/foo/foo.py?rev=142283&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/command_script/import/foo/foo.py (added)
+++ lldb/trunk/test/functionalities/command_script/import/foo/foo.py Mon Oct 17 16:45:27 2011
@@ -0,0 +1,3 @@
+def foo_function(debugger, args, result, dict):
+ result.Printf("foo says " + args)
+ return None
Added: lldb/trunk/test/functionalities/command_script/import/foo/foo2.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/command_script/import/foo/foo2.py?rev=142283&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/command_script/import/foo/foo2.py (added)
+++ lldb/trunk/test/functionalities/command_script/import/foo/foo2.py Mon Oct 17 16:45:27 2011
@@ -0,0 +1,7 @@
+def foo2_function(debugger, args, result, dict):
+ result.Printf("foo2 says " + args)
+ return None
+
+def __lldb_init_module(debugger, session_dict):
+ debugger.HandleCommand("command script add -f foo2.foo2_function foo2cmd")
+ return None
\ No newline at end of file
Added: lldb/trunk/test/functionalities/command_script/import/main.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/command_script/import/main.c?rev=142283&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/command_script/import/main.c (added)
+++ lldb/trunk/test/functionalities/command_script/import/main.c Mon Oct 17 16:45:27 2011
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+int main(int argc, char const *argv[]) {
+ printf("Hello world.\n"); // Set break point at this line.
+ if (argc == 1)
+ return 0;
+
+ // Waiting to be attached by the debugger, otherwise.
+ char line[100];
+ while (fgets(line, sizeof(line), stdin)) { // Waiting to be attached...
+ printf("input line=>%s\n", line);
+ }
+
+ printf("Exiting now\n");
+}
More information about the lldb-commits
mailing list