ferencd@0: #ifndef PYTHON_RUNNER_H ferencd@0: #define PYTHON_RUNNER_H ferencd@0: ferencd@0: #ifdef PYTHON_SCRIPTING ferencd@0: #include "pyembed.h" ferencd@0: #endif ferencd@0: ferencd@0: #include ferencd@0: #include ferencd@0: #include ferencd@0: ferencd@0: struct python_runner ferencd@0: { ferencd@0: ferencd@0: PyObject* pymodule = nullptr; ferencd@0: PyObject *main = nullptr; ferencd@0: ferencd@0: std::string buffer; ferencd@0: ferencd@0: explicit python_runner() ferencd@0: { ferencd@0: PyImport_AppendInittab("emb", emb::PyInit_emb); ferencd@0: Py_Initialize(); ferencd@0: ferencd@0: pymodule = PyImport_ImportModule("emb"); ferencd@0: main = PyImport_AddModule("__main__"); ferencd@0: } ferencd@0: ferencd@0: std::string run(std::map& kps, std::string between, const std::vector& all_variables) ferencd@0: { ferencd@0: std::string buffer; ferencd@0: emb::stdout_write_type write = [&buffer] (std::string s) { buffer += s; }; ferencd@0: emb::set_stdout(write); ferencd@0: ferencd@0: // generate a list of assignments to kp/kv values from the kps vector ferencd@0: std::set set_variables; ferencd@0: for(const auto& [kp, kv] : kps) ferencd@0: { ferencd@0: std::string cmd = kp + "='" + kv + "'\n"; ferencd@0: between = cmd + between; ferencd@0: set_variables.insert(kp); ferencd@0: } ferencd@0: ferencd@0: // here gather all the other variables that might have been in the template ferencd@0: for(const auto& v : all_variables) ferencd@0: { ferencd@0: if(set_variables.count(v) == 0) ferencd@0: { ferencd@0: std::string cmd = v + "=''\n"; ferencd@0: between = cmd + between; ferencd@0: set_variables.insert(v); ferencd@0: } ferencd@0: } ferencd@0: ferencd@0: // now gather all the structure definitions ferencd@0: ferencd@0: //std::cerr << "Trying to run:" << std::endl<< between << std::endl; ferencd@0: ferencd@0: PyRun_SimpleString(between.c_str()); ferencd@0: emb::reset_stdout(); ferencd@0: ferencd@0: PyObject *globals = PyModule_GetDict(main); ferencd@0: if(globals) ferencd@0: { ferencd@0: for(const auto& v : set_variables) ferencd@0: { ferencd@0: PyObject *a = PyDict_GetItemString(globals, v.c_str()); ferencd@0: if(a) ferencd@0: { ferencd@0: PyObject* temp_bytes = PyUnicode_AsEncodedString( a, "UTF-8", "strict" ); ferencd@0: if (temp_bytes) ferencd@0: { ferencd@0: std::string r = PyBytes_AS_STRING( temp_bytes ); ferencd@0: kps[v] = r; ferencd@0: ferencd@0: Py_DECREF( temp_bytes ); ferencd@0: } ferencd@0: Py_DECREF(a); ferencd@0: } ferencd@0: } ferencd@0: ferencd@0: Py_DECREF(globals); ferencd@0: } ferencd@0: ferencd@0: return buffer; ferencd@0: } ferencd@0: ferencd@0: virtual ~python_runner() ferencd@0: { ferencd@0: Py_DECREF(main); ferencd@0: Py_DECREF(pymodule); ferencd@0: Py_Finalize(); ferencd@0: } ferencd@0: ferencd@0: }; ferencd@0: ferencd@0: #endif // PYTHON_RUNNER_H