annotate 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
rev   line source
ferencd@0 1 #ifndef PYTHON_RUNNER_H
ferencd@0 2 #define PYTHON_RUNNER_H
ferencd@0 3
ferencd@0 4 #ifdef PYTHON_SCRIPTING
ferencd@0 5 #include "pyembed.h"
ferencd@0 6 #endif
ferencd@0 7
ferencd@0 8 #include <map>
ferencd@0 9 #include <string>
ferencd@0 10 #include <set>
ferencd@0 11
ferencd@0 12 struct python_runner
ferencd@0 13 {
ferencd@0 14
ferencd@0 15 PyObject* pymodule = nullptr;
ferencd@0 16 PyObject *main = nullptr;
ferencd@0 17
ferencd@0 18 std::string buffer;
ferencd@0 19
ferencd@0 20 explicit python_runner()
ferencd@0 21 {
ferencd@0 22 PyImport_AppendInittab("emb", emb::PyInit_emb);
ferencd@0 23 Py_Initialize();
ferencd@0 24
ferencd@0 25 pymodule = PyImport_ImportModule("emb");
ferencd@0 26 main = PyImport_AddModule("__main__");
ferencd@0 27 }
ferencd@0 28
ferencd@0 29 std::string run(std::map<std::string, std::string>& kps, std::string between, const std::vector<std::string>& all_variables)
ferencd@0 30 {
ferencd@0 31 std::string buffer;
ferencd@0 32 emb::stdout_write_type write = [&buffer] (std::string s) { buffer += s; };
ferencd@0 33 emb::set_stdout(write);
ferencd@0 34
ferencd@0 35 // generate a list of assignments to kp/kv values from the kps vector
ferencd@0 36 std::set<std::string> set_variables;
ferencd@0 37 for(const auto& [kp, kv] : kps)
ferencd@0 38 {
ferencd@0 39 std::string cmd = kp + "='" + kv + "'\n";
ferencd@0 40 between = cmd + between;
ferencd@0 41 set_variables.insert(kp);
ferencd@0 42 }
ferencd@0 43
ferencd@0 44 // here gather all the other variables that might have been in the template
ferencd@0 45 for(const auto& v : all_variables)
ferencd@0 46 {
ferencd@0 47 if(set_variables.count(v) == 0)
ferencd@0 48 {
ferencd@0 49 std::string cmd = v + "=''\n";
ferencd@0 50 between = cmd + between;
ferencd@0 51 set_variables.insert(v);
ferencd@0 52 }
ferencd@0 53 }
ferencd@0 54
ferencd@0 55 // now gather all the structure definitions
ferencd@0 56
ferencd@0 57 //std::cerr << "Trying to run:" << std::endl<< between << std::endl;
ferencd@0 58
ferencd@0 59 PyRun_SimpleString(between.c_str());
ferencd@0 60 emb::reset_stdout();
ferencd@0 61
ferencd@0 62 PyObject *globals = PyModule_GetDict(main);
ferencd@0 63 if(globals)
ferencd@0 64 {
ferencd@0 65 for(const auto& v : set_variables)
ferencd@0 66 {
ferencd@0 67 PyObject *a = PyDict_GetItemString(globals, v.c_str());
ferencd@0 68 if(a)
ferencd@0 69 {
ferencd@0 70 PyObject* temp_bytes = PyUnicode_AsEncodedString( a, "UTF-8", "strict" );
ferencd@0 71 if (temp_bytes)
ferencd@0 72 {
ferencd@0 73 std::string r = PyBytes_AS_STRING( temp_bytes );
ferencd@0 74 kps[v] = r;
ferencd@0 75
ferencd@0 76 Py_DECREF( temp_bytes );
ferencd@0 77 }
ferencd@0 78 Py_DECREF(a);
ferencd@0 79 }
ferencd@0 80 }
ferencd@0 81
ferencd@0 82 Py_DECREF(globals);
ferencd@0 83 }
ferencd@0 84
ferencd@0 85 return buffer;
ferencd@0 86 }
ferencd@0 87
ferencd@0 88 virtual ~python_runner()
ferencd@0 89 {
ferencd@0 90 Py_DECREF(main);
ferencd@0 91 Py_DECREF(pymodule);
ferencd@0 92 Py_Finalize();
ferencd@0 93 }
ferencd@0 94
ferencd@0 95 };
ferencd@0 96
ferencd@0 97 #endif // PYTHON_RUNNER_H