+static char* format_python_error(int space_nls) {
+ PyObject* extype = NULL, *exvalue = NULL, *extraceback = NULL;
+ PyObject* pextypestr = NULL, *pexvaluestr = NULL;
+ char* extypestr = NULL, *exvaluestr = NULL;
+ size_t retvallen = 0;
+ char* retval = NULL, *tmp;
+
+ PyErr_Fetch(&extype, &exvalue, &extraceback);
+ if (!extype)
+ goto cleanup;
+
+ pextypestr = PyObject_Str(extype);
+ if (!pextypestr)
+ goto cleanup;
+ extypestr = PyString_AsString(pextypestr);
+ if (!extypestr)
+ goto cleanup;
+
+ pexvaluestr = PyObject_Str(exvalue);
+ if (pexvaluestr)
+ exvaluestr = PyString_AsString(pexvaluestr);
+
+ retvallen = strlen(extypestr) + (exvaluestr ? strlen(exvaluestr) + 2 : 0) + 1;
+ retval = (char*)malloc(retvallen);
+ if (exvaluestr)
+ snprintf(retval, retvallen, "%s: %s", extypestr, exvaluestr);
+ else
+ strncpy(retval, extypestr, retvallen);
+
+ if (space_nls) {
+ tmp = retval;
+ while (*tmp) {
+ if (*tmp == '\n')
+ *tmp = ' ';
+ ++tmp;
+ }
+ }
+
+cleanup:
+ if (PyErr_Occurred())
+ PyErr_Clear(); /* ignore errors caused by formatting */
+ Py_XDECREF(extype);
+ Py_XDECREF(exvalue);
+ Py_XDECREF(extraceback);
+ Py_XDECREF(pextypestr);
+ Py_XDECREF(pexvaluestr);
+
+ if (retval)
+ return retval;
+
+ return strdup("unknown exception");
+}
+
+static int python_run_statements(char const* msg, char** err) {
+ PyObject* o;
+ char* exmsg = NULL;
+ PyObject* py_main_module = NULL;
+ PyObject* py_globals;
+
+ py_main_module = PyImport_AddModule("__main__");
+ if (!py_main_module) {
+ exmsg = format_python_error(1);
+ if (exmsg)
+ *err = exmsg;
+ else
+ *err = strdup("unknown exception");
+ return 1;
+ }
+
+ py_globals = PyModule_GetDict(py_main_module);
+
+ o = PyRun_String(msg, Py_file_input, py_globals, py_globals);
+ if (o == NULL) {
+ exmsg = format_python_error(1);
+ if (exmsg)
+ *err = exmsg;
+ else
+ *err = strdup("unknown exception");
+ return 1;
+ }
+ else {
+ Py_DECREF(o);
+ }
+
+ return 0;
+}
+