diff --git a/Sources/Plasma/FeatureLib/pfConsole/pfConsoleCommands.cpp b/Sources/Plasma/FeatureLib/pfConsole/pfConsoleCommands.cpp index 7cd34f04..3be35266 100644 --- a/Sources/Plasma/FeatureLib/pfConsole/pfConsoleCommands.cpp +++ b/Sources/Plasma/FeatureLib/pfConsole/pfConsoleCommands.cpp @@ -6933,38 +6933,6 @@ PF_CONSOLE_CMD( KI, // Group name PF_CONSOLE_GROUP( Python ) // Defines a main command group -PF_CONSOLE_CMD( Python, // Group name - RunFile, // Function name - "string filename", // Params - "Run the specified Python file program" ) // Help string -{ - // now evaluate this mess they made - PyObject* mymod = PythonInterface::FindModule("__main__"); - // make sure the filename doesn't have the .py extension (import doesn't need it) - char importname[200]; - int i; - for (i=0; i<199; i++ ) - { - char ch = ((const char*)params[0])[i]; - // if we are at the end of the string or at a dot, truncate here - if ( ch == '.' || ch == 0 ) - break; - else - importname[i] = ((const char*)params[0])[i]; - } - importname[i] = 0; - - // create the line to execute the file - char runline[256]; - sprintf(runline,"import %s", importname); - PythonInterface::RunString(runline,mymod); - std::string output; - // get the messages - PythonInterface::getOutputAndReset(&output); - PrintString(output.c_str()); -} - - #include "pfPython/cyMisc.h" PF_CONSOLE_CMD( Python, // Group name @@ -7006,16 +6974,17 @@ PF_CONSOLE_CMD( Python, "string functions, ...", // Params "Run a cheat command" ) { - const char* extraParms = ""; - if (numParams > 1) - extraParms = params[1]; - // now evaluate this mess they made - PyObject* mymod = PythonInterface::FindModule("__main__"); + plString args; + if (numParams > 1) + { + const char* tmp = params[1]; + args = plString::Format("(%s,)", tmp); + } + else + args = _TEMP_CONVERT_FROM_LITERAL("()"); + + PythonInterface::RunFunctionSafe("xCheat", params[0], args.c_str()); - // create the line to execute the file - char runline[256]; - sprintf(runline,"import xCheat;xCheat.%s('%s')", (const char*)params[0],extraParms); - PythonInterface::RunString(runline,mymod); std::string output; // get the messages PythonInterface::getOutputAndReset(&output); diff --git a/Sources/Plasma/FeatureLib/pfPython/cyPythonInterface.cpp b/Sources/Plasma/FeatureLib/pfPython/cyPythonInterface.cpp index 32b05661..f0ba7276 100644 --- a/Sources/Plasma/FeatureLib/pfPython/cyPythonInterface.cpp +++ b/Sources/Plasma/FeatureLib/pfPython/cyPythonInterface.cpp @@ -1932,6 +1932,20 @@ void PythonInterface::WriteToStdErr(const char* text) } } +PyObject* PythonInterface::ImportModule(const char* module) +{ + PyObject* result = nil; + PyObject* name = PyString_FromString(module); + + if (name != nil) + { + result = PyImport_Import(name); + Py_DECREF(name); + } + + return result; +} + ///////////////////////////////////////////////////////////////////////////// // // Function : FindModule @@ -2280,6 +2294,78 @@ bool PythonInterface::RunPYC(PyObject* code, PyObject* module) return true; } +///////////////////////////////////////////////////////////////////////////// +// +// Function : RunFunction +// PARAMETERS : module - module name to run 'name' in +// : name - name of function +// : args - tuple with arguments +// +// +PyObject* PythonInterface::RunFunction(PyObject* module, const char* name, PyObject* args) +{ + if (module == NULL) + return NULL; + + PyObject* function = PyObject_GetAttrString(module, name); + + PyObject* result = NULL; + if (function != nil) + { + result = PyObject_Call(function, args, NULL); + Py_DECREF(function); + } + + return result; +} + +PyObject* PythonInterface::ParseArgs(const char* args) +{ + PyObject* result = NULL; + PyObject* scope = PyDict_New(); + if (scope) + { + //- Py_eval_input makes this function accept only single expresion (not statement) + //- When using empty scope, functions and classes like 'file' or '__import__' are not visible + result = PyRun_String(args, Py_eval_input, scope, NULL); + Py_DECREF(scope); + } + + return result; +} + +bool PythonInterface::RunFunctionSafe(const char* module, const char* function, const char* args) +{ + PyObject* moduleObj = ImportModule(module); + bool result = false; + if (moduleObj) + { + PyObject* argsObj = ParseArgs(args); + if (argsObj) + { + PyObject* callResult = RunFunction(moduleObj, function, argsObj); + if (callResult) + { + result = true; + Py_DECREF(callResult); + } + + Py_DECREF(argsObj); + } + Py_DECREF(moduleObj); + } + + if (!result) + { + PyErr_Print(); + + if (Py_FlushLine()) + PyErr_Clear(); + } + + return result; +} + ///////////////////////////////////////////////////////////////////////////// // // Function : GetpyKeyFromPython diff --git a/Sources/Plasma/FeatureLib/pfPython/cyPythonInterface.h b/Sources/Plasma/FeatureLib/pfPython/cyPythonInterface.h index 3d7eaa72..2df041d7 100644 --- a/Sources/Plasma/FeatureLib/pfPython/cyPythonInterface.h +++ b/Sources/Plasma/FeatureLib/pfPython/cyPythonInterface.h @@ -48,6 +48,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com // #include "HeadSpin.h" #include "hsStlUtils.h" +#include "plString.h" #if defined(HAVE_CYPYTHONIDE) && !defined(PLASMA_EXTERNAL_RELEASE) #include "../../Apps/CyPythonIDE/plCyDebug/plCyDebServer.h" @@ -139,6 +140,8 @@ public: // Writes 'text' to stderr specified in the python interface static void WriteToStdErr(const char* text); + static PyObject* ImportModule(const char* module); + // Find module. If it doesn't exist then don't create, return nil. static PyObject* FindModule(const char* module); @@ -220,6 +223,11 @@ public: // static bool RunPYC(PyObject* code, PyObject* module); + static PyObject* RunFunction(PyObject* module, const char* name, PyObject* args); + + static PyObject* ParseArgs(const char* args); + + static bool RunFunctionSafe(const char* module, const char* function, const char* args); ///////////////////////////////////////////////////////////////////////////// // // Function : GetpyKeyFromPython