diff options
author | Caroline Tice <ctice@apple.com> | 2011-01-14 21:09:29 +0000 |
---|---|---|
committer | Caroline Tice <ctice@apple.com> | 2011-01-14 21:09:29 +0000 |
commit | 8f5b2eb1e21f37d8a470fda4c8d1741ceb8b6d81 (patch) | |
tree | c21f0aaa3ff9f64b08e68b3649d98444a1bc1f16 /lldb/source/Interpreter/ScriptInterpreterPython.cpp | |
parent | c6c7ca58e4ce298c4f1a9cfa192af3c2ad49a5c6 (diff) | |
download | bcm5719-llvm-8f5b2eb1e21f37d8a470fda4c8d1741ceb8b6d81.tar.gz bcm5719-llvm-8f5b2eb1e21f37d8a470fda4c8d1741ceb8b6d81.zip |
Recent modifications to the Python script interpreter caused some problems
when handling one-liner commands that contain escaped characters. In
order to deal with the new namespace/dictionary stuff, the command was
being embedded within a second string, which messed up the escaping.
This fixes the problem by handling one-liners in a different manner, so they
no longer need to be embedded within another string, and can still be
processed in the proper namespace/dictionary context.
llvm-svn: 123467
Diffstat (limited to 'lldb/source/Interpreter/ScriptInterpreterPython.cpp')
-rw-r--r-- | lldb/source/Interpreter/ScriptInterpreterPython.cpp | 93 |
1 files changed, 87 insertions, 6 deletions
diff --git a/lldb/source/Interpreter/ScriptInterpreterPython.cpp b/lldb/source/Interpreter/ScriptInterpreterPython.cpp index c6d4504b170..9411e433e24 100644 --- a/lldb/source/Interpreter/ScriptInterpreterPython.cpp +++ b/lldb/source/Interpreter/ScriptInterpreterPython.cpp @@ -326,17 +326,98 @@ ScriptInterpreterPython::ExecuteOneLine (const char *command, CommandReturnObjec Mutex::Locker locker (GetPythonMutex()); + // We want to call run_one_line, passing in the dictionary and the command string. We cannot do this through + // PyRun_SimpleString here because the command string may contain escaped characters, and putting it inside + // another string to pass to PyRun_SimpleString messes up the escaping. So we use the following more complicated + // method to pass the command string directly down to Python. + + + bool success = false; + if (command) { - int success; + // Find the correct script interpreter dictionary in the main module. + PyObject *main_mod = PyImport_AddModule ("__main__"); + PyObject *script_interpreter_dict = NULL; + if (main_mod != NULL) + { + PyObject *main_dict = PyModule_GetDict (main_mod); + if ((main_dict != NULL) + && PyDict_Check (main_dict)) + { + // Go through the main dictionary looking for the correct python script interpreter dictionary + PyObject *key, *value; + Py_ssize_t pos = 0; + + while (PyDict_Next (main_dict, &pos, &key, &value)) + { + // We have stolen references to the key and value objects in the dictionary; we need to increment + // them now so that Python's garbage collector doesn't collect them out from under us. + Py_INCREF (key); + Py_INCREF (value); + if (strcmp (PyString_AsString (key), m_dictionary_name.c_str()) == 0) + { + script_interpreter_dict = value; + break; + } + } + } + + if (script_interpreter_dict != NULL) + { + PyObject *pfunc = NULL; + PyObject *pmod = PyImport_AddModule ("embedded_interpreter"); + if (pmod != NULL) + { + PyObject *pmod_dict = PyModule_GetDict (pmod); + if ((pmod_dict != NULL) + && PyDict_Check (pmod_dict)) + { + PyObject *key, *value; + Py_ssize_t pos = 0; + + while (PyDict_Next (pmod_dict, &pos, &key, &value)) + { + Py_INCREF (key); + Py_INCREF (value); + if (strcmp (PyString_AsString (key), "run_one_line") == 0) + { + pfunc = value; + break; + } + } + + PyObject *string_arg = PyString_FromString (command); + if (pfunc && string_arg && PyCallable_Check (pfunc)) + { + PyObject *pargs = PyTuple_New (2); + if (pargs != NULL) + { + PyTuple_SetItem (pargs, 0, script_interpreter_dict); + PyTuple_SetItem (pargs, 1, string_arg); + PyObject *pvalue = PyObject_CallObject (pfunc, pargs); + Py_DECREF (pargs); + if (pvalue != NULL) + { + Py_DECREF (pvalue); + success = true; + } + else if (PyErr_Occurred ()) + { + PyErr_Print(); + PyErr_Clear(); + } + } + } + } + } + Py_INCREF (script_interpreter_dict); + } + } - StreamString sstr; - sstr.Printf ("run_one_line (%s, '%s')", m_dictionary_name.c_str(), command); - success = PyRun_SimpleString (sstr.GetData()); - LeaveSession (); - if (success == 0) + if (success) return true; // The one-liner failed. Append the error message. |