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