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
This commit is contained in:
parent
c6c7ca58e4
commit
8f5b2eb1e2
|
@ -355,10 +355,10 @@ CommandObjectSettingsShow::Execute (Args& command,
|
|||
}
|
||||
else
|
||||
{
|
||||
StreamString tmp_str;
|
||||
char *type_name = (char *) "";
|
||||
if (var_type != eSetVarTypeNone)
|
||||
{
|
||||
StreamString tmp_str;
|
||||
tmp_str.Printf (" (%s)", UserSettingsController::GetTypeString (var_type));
|
||||
type_name = (char *) tmp_str.GetData();
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue