gnm-py-interpreter.c (gnumeric-1.12.49.tar.xz) | : | gnm-py-interpreter.c (gnumeric-1.12.50.tar.xz) | ||
---|---|---|---|---|
skipping to change at line 20 | skipping to change at line 20 | |||
#include <gutils.h> | #include <gutils.h> | |||
#include "py-gnumeric.h" | #include "py-gnumeric.h" | |||
#include "gnm-py-interpreter.h" | #include "gnm-py-interpreter.h" | |||
#include "gnm-python.h" | #include "gnm-python.h" | |||
#include <goffice/goffice.h> | #include <goffice/goffice.h> | |||
#include <goffice/app/module-plugin-defs.h> | #include <goffice/app/module-plugin-defs.h> | |||
#include <gsf/gsf-impl-utils.h> | #include <gsf/gsf-impl-utils.h> | |||
#include <glib/gi18n-lib.h> | #include <glib/gi18n-lib.h> | |||
// Like PyDict_SetItemString, but takes ownership of val | ||||
static void | ||||
gnm_py_dict_store (PyObject *dict, const char *key, PyObject *val) | ||||
{ | ||||
PyDict_SetItemString (dict, key, val); | ||||
Py_DECREF (val); | ||||
} | ||||
struct _GnmPyInterpreter { | struct _GnmPyInterpreter { | |||
GObject parent_instance; | GObject parent_instance; | |||
PyThreadState *py_thread_state; | PyThreadState *py_thread_state; | |||
PyTypeObject *stringio_class; | PyTypeObject *stringio_class; | |||
GOPlugin *plugin; | GOPlugin *plugin; | |||
}; | }; | |||
typedef struct { | typedef struct { | |||
GObjectClass parent_class; | GObjectClass parent_class; | |||
skipping to change at line 55 | skipping to change at line 63 | |||
interpreter->py_thread_state = NULL; | interpreter->py_thread_state = NULL; | |||
interpreter->stringio_class = NULL; | interpreter->stringio_class = NULL; | |||
interpreter->plugin = NULL; | interpreter->plugin = NULL; | |||
} | } | |||
static void | static void | |||
gnm_py_interpreter_finalize (GObject *obj) | gnm_py_interpreter_finalize (GObject *obj) | |||
{ | { | |||
GnmPyInterpreter *interpreter = GNM_PY_INTERPRETER (obj); | GnmPyInterpreter *interpreter = GNM_PY_INTERPRETER (obj); | |||
if (interpreter->stringio_class != NULL) { | Py_CLEAR (interpreter->stringio_class); | |||
Py_DECREF (interpreter->stringio_class); | ||||
} | ||||
parent_class->finalize (obj); | parent_class->finalize (obj); | |||
} | } | |||
static void | static void | |||
gnm_py_interpreter_class_init (GObjectClass *gobject_class) | gnm_py_interpreter_class_init (GObjectClass *gobject_class) | |||
{ | { | |||
parent_class = g_type_class_peek_parent (gobject_class); | parent_class = g_type_class_peek_parent (gobject_class); | |||
gobject_class->finalize = gnm_py_interpreter_finalize; | gobject_class->finalize = gnm_py_interpreter_finalize; | |||
skipping to change at line 91 | skipping to change at line 96 | |||
GnmPyInterpreter * | GnmPyInterpreter * | |||
gnm_py_interpreter_new (GOPlugin *plugin) | gnm_py_interpreter_new (GOPlugin *plugin) | |||
{ | { | |||
GnmPyInterpreter *interpreter; | GnmPyInterpreter *interpreter; | |||
PyThreadState *py_thread_state; | PyThreadState *py_thread_state; | |||
g_return_val_if_fail (plugin == NULL || GO_IS_PLUGIN (plugin), NULL); | g_return_val_if_fail (plugin == NULL || GO_IS_PLUGIN (plugin), NULL); | |||
if (plugin != NULL) { | if (plugin != NULL) { | |||
PyThreadState* main_ = PyThreadState_Get (); | ||||
py_thread_state = Py_NewInterpreter (); | py_thread_state = Py_NewInterpreter (); | |||
PyThreadState_Swap (main_); | ||||
} else { | } else { | |||
py_thread_state = PyThreadState_Get (); | py_thread_state = PyThreadState_Get (); | |||
} | } | |||
g_return_val_if_fail (py_thread_state != NULL, NULL); | ||||
interpreter = g_object_new (GNM_PY_INTERPRETER_TYPE, NULL); | interpreter = g_object_new (GNM_PY_INTERPRETER_TYPE, NULL); | |||
interpreter->py_thread_state = py_thread_state; | interpreter->py_thread_state = py_thread_state; | |||
interpreter->plugin = plugin; | interpreter->plugin = plugin; | |||
PySys_SetArgv (G_N_ELEMENTS (plugin_argv) - 1, plugin_argv); | PySys_SetArgv (G_N_ELEMENTS (plugin_argv) - 1, plugin_argv); | |||
gnm_py_interpreter_switch_to (interpreter); | ||||
if (plugin != NULL) | if (plugin != NULL) { | |||
py_gnumeric_add_plugin (py_initgnumeric (), interpreter); | py_gnumeric_add_plugin (py_initgnumeric (), interpreter); | |||
} | ||||
return interpreter; | return interpreter; | |||
} | } | |||
void | void | |||
gnm_py_interpreter_destroy (GnmPyInterpreter *interpreter, | gnm_py_interpreter_destroy (GnmPyInterpreter *interpreter, | |||
GnmPyInterpreter *new_interpreter) | GnmPyInterpreter *new_interpreter) | |||
{ | { | |||
g_return_if_fail (GNM_IS_PY_INTERPRETER (interpreter)); | g_return_if_fail (GNM_IS_PY_INTERPRETER (interpreter)); | |||
gnm_py_interpreter_switch_to (interpreter); | if (interpreter->plugin != NULL) { | |||
Py_EndInterpreter (interpreter->py_thread_state); | gnm_py_interpreter_switch_to (interpreter); | |||
Py_EndInterpreter (interpreter->py_thread_state); | ||||
} | ||||
(void) PyThreadState_Swap (new_interpreter->py_thread_state); | (void) PyThreadState_Swap (new_interpreter->py_thread_state); | |||
interpreter->py_thread_state = NULL; | interpreter->py_thread_state = NULL; | |||
g_object_unref (interpreter); | g_object_unref (interpreter); | |||
} | } | |||
void | void | |||
gnm_py_interpreter_switch_to (GnmPyInterpreter *interpreter) | gnm_py_interpreter_switch_to (GnmPyInterpreter *interpreter) | |||
{ | { | |||
g_return_if_fail (GNM_IS_PY_INTERPRETER (interpreter)); | g_return_if_fail (GNM_IS_PY_INTERPRETER (interpreter)); | |||
if (PyThreadState_Get ()->interp != interpreter->py_thread_state->interp) | if (PyThreadState_Get () != interpreter->py_thread_state) { | |||
{ | // g_printerr ("Switching to %p\n", interpreter->py_thread_state) | |||
; | ||||
(void) PyThreadState_Swap (interpreter->py_thread_state); | (void) PyThreadState_Swap (interpreter->py_thread_state); | |||
g_signal_emit ( | g_signal_emit (interpreter, signals[SET_CURRENT_SIGNAL], 0); | |||
interpreter, signals[SET_CURRENT_SIGNAL], 0); | } else { | |||
// g_printerr ("Not switching to %p\n", PyThreadState_Get ()); | ||||
} | } | |||
} | } | |||
static void | static void | |||
run_print_string (const char *cmd, PyObject *stdout_obj) | run_print_string (const char *cmd, PyObject *stdout_obj) | |||
{ | { | |||
PyObject *m, *d, *v; | PyObject *m, *d, *v; | |||
m = PyImport_AddModule ((char *) "__main__"); | m = PyImport_AddModule ("__main__"); | |||
if (m == NULL) | if (m == NULL) | |||
return; | return; | |||
d = PyModule_GetDict (m); | d = PyModule_GetDict (m); | |||
v = PyRun_String ((char *) cmd, Py_single_input, d, d); | v = PyRun_String (cmd, Py_single_input, d, d); | |||
if (!v) | if (!v) | |||
PyErr_Print (); | PyErr_Print (); | |||
if (PyFile_WriteString ("\n", stdout_obj) != 0) | if (PyFile_WriteString ("\n", stdout_obj) != 0) | |||
PyErr_Clear (); | PyErr_Clear (); | |||
if (v && v != Py_None && stdout_obj) { | if (v && v != Py_None && stdout_obj) { | |||
if (PyFile_WriteObject (v, stdout_obj, Py_PRINT_RAW) != 0) | if (PyFile_WriteObject (v, stdout_obj, Py_PRINT_RAW) != 0) | |||
PyErr_Clear (); | PyErr_Clear (); | |||
} | } | |||
if (v) { | Py_XDECREF (v); | |||
Py_DECREF (v); | ||||
} | ||||
} | } | |||
void | void | |||
gnm_py_interpreter_run_string (GnmPyInterpreter *interpreter, const char *cmd, | gnm_py_interpreter_run_string (GnmPyInterpreter *interpreter, const char *cmd, | |||
char **opt_stdout, char **opt_stderr) | char **opt_stdout, char **opt_stderr) | |||
{ | { | |||
PyObject *sys_module, *sys_module_dict; | PyObject *sys_module, *sys_module_dict; | |||
PyObject *saved_stdout_obj = NULL, *stdout_obj = NULL, | PyObject *saved_stdout_obj = NULL, *stdout_obj = NULL, | |||
*saved_stderr_obj = NULL, *stderr_obj = NULL; | *saved_stderr_obj = NULL, *stderr_obj = NULL; | |||
PyObject *py_str; | PyObject *py_str; | |||
g_return_if_fail (GNM_IS_PY_INTERPRETER (interpreter)); | g_return_if_fail (GNM_IS_PY_INTERPRETER (interpreter)); | |||
gnm_py_interpreter_switch_to (interpreter); | gnm_py_interpreter_switch_to (interpreter); | |||
sys_module = PyImport_AddModule ((char *) "sys"); | sys_module = PyImport_AddModule ("sys"); | |||
if (sys_module == NULL) | if (sys_module == NULL) | |||
PyErr_Print (); | PyErr_Print (); | |||
g_return_if_fail (sys_module != NULL); | g_return_if_fail (sys_module != NULL); | |||
sys_module_dict = PyModule_GetDict (sys_module); | sys_module_dict = PyModule_GetDict (sys_module); | |||
g_return_if_fail (sys_module_dict != NULL); | g_return_if_fail (sys_module_dict != NULL); | |||
if (interpreter->stringio_class == NULL) { | if (interpreter->stringio_class == NULL) { | |||
PyObject *stringio_module, *stringio_module_dict, *sublist; | PyObject *stringio_module, *stringio_module_dict, *sublist; | |||
sublist = PyList_New (0); | sublist = PyList_New (0); | |||
PyList_Insert (sublist, 0, PyUnicode_FromString ((char const *) " | PyList_Insert (sublist, 0, PyUnicode_FromString ("StringIO")); | |||
StringIO")); | stringio_module = PyImport_ImportModule ("io"); | |||
stringio_module = PyImport_ImportModule ((char const *) "io"); | ||||
Py_DECREF (sublist); | Py_DECREF (sublist); | |||
if (stringio_module == NULL) | if (stringio_module == NULL) | |||
PyErr_Print (); | PyErr_Print (); | |||
g_return_if_fail (stringio_module != NULL); | g_return_if_fail (stringio_module != NULL); | |||
stringio_module_dict = PyModule_GetDict (stringio_module); | stringio_module_dict = PyModule_GetDict (stringio_module); | |||
g_return_if_fail (stringio_module_dict != NULL); | g_return_if_fail (stringio_module_dict != NULL); | |||
interpreter->stringio_class = | interpreter->stringio_class = | |||
(PyTypeObject *) PyDict_GetItemString (stringio_m odule_dict, | (PyTypeObject *) PyDict_GetItemString (stringio_m odule_dict, | |||
(char *) "StringIO"); | "StringIO" ); | |||
g_return_if_fail (interpreter->stringio_class != NULL); | g_return_if_fail (interpreter->stringio_class != NULL); | |||
Py_INCREF (interpreter->stringio_class); | Py_INCREF (interpreter->stringio_class); | |||
} | } | |||
if (opt_stdout != NULL) { | if (opt_stdout != NULL) { | |||
stdout_obj = PyType_GenericNew(interpreter->stringio_class, | stdout_obj = PyType_GenericNew(interpreter->stringio_class, | |||
NULL, NULL); | NULL, NULL); | |||
if (stdout_obj == NULL) | if (stdout_obj == NULL) | |||
PyErr_Print (); | PyErr_Print (); | |||
g_return_if_fail (stdout_obj != NULL); | g_return_if_fail (stdout_obj != NULL); | |||
PyObject_CallMethod (stdout_obj, (char *) "__init__", NULL); | PyObject_CallMethod (stdout_obj, "__init__", NULL); | |||
saved_stdout_obj = PyDict_GetItemString (sys_module_dict, | saved_stdout_obj = PyDict_GetItemString (sys_module_dict, | |||
(char *) "stdout"); | "stdout"); | |||
g_return_if_fail (saved_stdout_obj != NULL); | g_return_if_fail (saved_stdout_obj != NULL); | |||
Py_INCREF (saved_stdout_obj); | Py_INCREF (saved_stdout_obj); | |||
PyDict_SetItemString (sys_module_dict, (char *) "stdout", | PyDict_SetItemString (sys_module_dict, "stdout", stdout_obj); | |||
stdout_obj); | // We still own a ref to stdout_obj | |||
} | } | |||
if (opt_stderr != NULL) { | if (opt_stderr != NULL) { | |||
stderr_obj = PyType_GenericNew(interpreter->stringio_class, | stderr_obj = PyType_GenericNew(interpreter->stringio_class, | |||
NULL, NULL); | NULL, NULL); | |||
if (stderr_obj == NULL) | if (stderr_obj == NULL) | |||
PyErr_Print (); | PyErr_Print (); | |||
g_return_if_fail (stderr_obj != NULL); | g_return_if_fail (stderr_obj != NULL); | |||
PyObject_CallMethod (stderr_obj, (char *) "__init__", NULL); | PyObject_CallMethod (stderr_obj, "__init__", NULL); | |||
saved_stderr_obj = PyDict_GetItemString (sys_module_dict, | saved_stderr_obj = PyDict_GetItemString (sys_module_dict, | |||
(char *) "stderr"); | "stderr"); | |||
g_return_if_fail (saved_stderr_obj != NULL); | g_return_if_fail (saved_stderr_obj != NULL); | |||
Py_INCREF (saved_stderr_obj); | Py_INCREF (saved_stderr_obj); | |||
PyDict_SetItemString (sys_module_dict, (char *) "stderr", | PyDict_SetItemString (sys_module_dict, "stderr", stderr_obj); | |||
stderr_obj); | // We still own a ref to stderr_obj | |||
} | } | |||
run_print_string (cmd, stdout_obj); | run_print_string (cmd, stdout_obj); | |||
if (opt_stdout != NULL) { | if (opt_stdout != NULL) { | |||
PyDict_SetItemString (sys_module_dict, (char *) "stdout", | gnm_py_dict_store (sys_module_dict, "stdout", saved_stdout_obj); | |||
saved_stdout_obj); | py_str = PyObject_CallMethod (stdout_obj, "getvalue", NULL); | |||
Py_DECREF (saved_stdout_obj); | ||||
py_str = PyObject_CallMethod (stdout_obj, (char *) "getvalue", | ||||
NULL); | ||||
if (py_str && PyUnicode_Check (py_str)) | if (py_str && PyUnicode_Check (py_str)) | |||
*opt_stdout = g_strdup (PyUnicode_AsUTF8 (py_str)); | *opt_stdout = g_strdup (PyUnicode_AsUTF8 (py_str)); | |||
else | else | |||
*opt_stdout = NULL; | *opt_stdout = NULL; | |||
if (py_str == NULL) | if (py_str == NULL) | |||
PyErr_Print (); | PyErr_Print (); | |||
Py_DECREF (stdout_obj); | Py_DECREF (stdout_obj); | |||
} | } | |||
if (opt_stderr != NULL) { | if (opt_stderr != NULL) { | |||
PyDict_SetItemString (sys_module_dict, (char *) "stderr", | gnm_py_dict_store (sys_module_dict, "stderr", saved_stderr_obj); | |||
saved_stderr_obj); | py_str = PyObject_CallMethod (stderr_obj, "getvalue", NULL); | |||
Py_DECREF (saved_stderr_obj); | ||||
py_str = PyObject_CallMethod (stderr_obj, (char *) "getvalue", | ||||
NULL); | ||||
if (py_str && PyUnicode_Check (py_str)) | if (py_str && PyUnicode_Check (py_str)) | |||
*opt_stderr = g_strdup (PyUnicode_AsUTF8 (py_str)); | *opt_stderr = g_strdup (PyUnicode_AsUTF8 (py_str)); | |||
else | else | |||
*opt_stderr = NULL; | *opt_stderr = NULL; | |||
if (py_str == NULL) | if (py_str == NULL) | |||
PyErr_Print (); | PyErr_Print (); | |||
Py_DECREF (stderr_obj); | Py_DECREF (stderr_obj); | |||
} | } | |||
} | } | |||
skipping to change at line 277 | skipping to change at line 279 | |||
g_return_val_if_fail (GNM_IS_PY_INTERPRETER (interpreter), NULL); | g_return_val_if_fail (GNM_IS_PY_INTERPRETER (interpreter), NULL); | |||
return interpreter->plugin; | return interpreter->plugin; | |||
} | } | |||
int | int | |||
gnm_py_interpreter_compare (gconstpointer a, gconstpointer b) | gnm_py_interpreter_compare (gconstpointer a, gconstpointer b) | |||
{ | { | |||
const GnmPyInterpreter *int_a = a, *int_b = b; | const GnmPyInterpreter *int_a = a, *int_b = b; | |||
if (int_a->plugin == NULL && int_b->plugin == NULL) { | if (int_a->plugin == int_b->plugin) { | |||
return 0; | return 0; | |||
} else if (int_a->plugin == NULL) { | } else if (int_a->plugin == NULL) { | |||
return -1; | return -1; | |||
} else if (int_b->plugin == NULL) { | } else if (int_b->plugin == NULL) { | |||
return 1; | return 1; | |||
} else { | } else { | |||
return g_utf8_collate (go_plugin_get_name (int_a->plugin), | return g_utf8_collate (go_plugin_get_name (int_a->plugin), | |||
go_plugin_get_name (int_b->plugin)); | go_plugin_get_name (int_b->plugin)); | |||
} | } | |||
} | } | |||
End of changes. 28 change blocks. | ||||
45 lines changed or deleted | 46 lines changed or added |