Mercurial > thymian
diff templates/python_runner.h @ 0:a4671277546c tip
created the repository for the thymian project
| author | ferencd |
|---|---|
| date | Tue, 17 Aug 2021 11:19:54 +0200 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/python_runner.h Tue Aug 17 11:19:54 2021 +0200 @@ -0,0 +1,97 @@ +#ifndef PYTHON_RUNNER_H +#define PYTHON_RUNNER_H + +#ifdef PYTHON_SCRIPTING +#include "pyembed.h" +#endif + +#include <map> +#include <string> +#include <set> + +struct python_runner +{ + + PyObject* pymodule = nullptr; + PyObject *main = nullptr; + + std::string buffer; + + explicit python_runner() + { + PyImport_AppendInittab("emb", emb::PyInit_emb); + Py_Initialize(); + + pymodule = PyImport_ImportModule("emb"); + main = PyImport_AddModule("__main__"); + } + + std::string run(std::map<std::string, std::string>& kps, std::string between, const std::vector<std::string>& all_variables) + { + std::string buffer; + emb::stdout_write_type write = [&buffer] (std::string s) { buffer += s; }; + emb::set_stdout(write); + + // generate a list of assignments to kp/kv values from the kps vector + std::set<std::string> set_variables; + for(const auto& [kp, kv] : kps) + { + std::string cmd = kp + "='" + kv + "'\n"; + between = cmd + between; + set_variables.insert(kp); + } + + // here gather all the other variables that might have been in the template + for(const auto& v : all_variables) + { + if(set_variables.count(v) == 0) + { + std::string cmd = v + "=''\n"; + between = cmd + between; + set_variables.insert(v); + } + } + + // now gather all the structure definitions + + //std::cerr << "Trying to run:" << std::endl<< between << std::endl; + + PyRun_SimpleString(between.c_str()); + emb::reset_stdout(); + + PyObject *globals = PyModule_GetDict(main); + if(globals) + { + for(const auto& v : set_variables) + { + PyObject *a = PyDict_GetItemString(globals, v.c_str()); + if(a) + { + PyObject* temp_bytes = PyUnicode_AsEncodedString( a, "UTF-8", "strict" ); + if (temp_bytes) + { + std::string r = PyBytes_AS_STRING( temp_bytes ); + kps[v] = r; + + Py_DECREF( temp_bytes ); + } + Py_DECREF(a); + } + } + + Py_DECREF(globals); + } + + return buffer; + } + + virtual ~python_runner() + { + Py_DECREF(main); + Py_DECREF(pymodule); + Py_Finalize(); + } + +}; + +#endif // PYTHON_RUNNER_H
