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