comparison templates/pyembed.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 PYEMBED_H
2 #define PYEMBED_H
3
4 //
5 // Copyright (C) 2011 Mateusz Loskot <mateusz@loskot.net>
6 // Distributed under the Boost Software License, Version 1.0.
7 // (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9 //
10 // Blog article: http://mateusz.loskot.net/?p=2819
11
12 #include <functional>
13 #include <iostream>
14 #include <string>
15 #include <Python.h>
16
17 namespace emb
18 {
19
20 typedef std::function<void(std::string)> stdout_write_type;
21
22 struct Stdout
23 {
24 PyObject_HEAD
25 stdout_write_type write;
26 };
27
28 PyObject* Stdout_write(PyObject* self, PyObject* args)
29 {
30 std::size_t written(0);
31 Stdout* selfimpl = reinterpret_cast<Stdout*>(self);
32 if (selfimpl->write)
33 {
34 char* data;
35 if (!PyArg_ParseTuple(args, "s", &data))
36 return 0;
37
38 std::string str(data);
39 selfimpl->write(str);
40 written = str.size();
41 }
42 return PyLong_FromSize_t(written);
43 }
44
45 PyObject* Stdout_flush(PyObject* /*self*/, PyObject* /*args*/)
46 {
47 // no-op
48 return Py_BuildValue("");
49 }
50
51 PyMethodDef Stdout_methods[] =
52 {
53 {"write", Stdout_write, METH_VARARGS, "sys.stdout.write"},
54 {"flush", Stdout_flush, METH_VARARGS, "sys.stdout.write"},
55 {0, 0, 0, 0} // sentinel
56 };
57
58 PyTypeObject StdoutType =
59 {
60 PyVarObject_HEAD_INIT(0, 0)
61 "emb.StdoutType", /* tp_name */
62 sizeof(Stdout), /* tp_basicsize */
63 0, /* tp_itemsize */
64 0, /* tp_dealloc */
65 0, /* tp_print */
66 0, /* tp_getattr */
67 0, /* tp_setattr */
68 0, /* tp_reserved */
69 0, /* tp_repr */
70 0, /* tp_as_number */
71 0, /* tp_as_sequence */
72 0, /* tp_as_mapping */
73 0, /* tp_hash */
74 0, /* tp_call */
75 0, /* tp_str */
76 0, /* tp_getattro */
77 0, /* tp_setattro */
78 0, /* tp_as_buffer */
79 Py_TPFLAGS_DEFAULT, /* tp_flags */
80 "emb.Stdout objects", /* tp_doc */
81 0, /* tp_traverse */
82 0, /* tp_clear */
83 0, /* tp_richcompare */
84 0, /* tp_weaklistoffset */
85 0, /* tp_iter */
86 0, /* tp_iternext */
87 Stdout_methods, /* tp_methods */
88 0, /* tp_members */
89 0, /* tp_getset */
90 0, /* tp_base */
91 0, /* tp_dict */
92 0, /* tp_descr_get */
93 0, /* tp_descr_set */
94 0, /* tp_dictoffset */
95 0, /* tp_init */
96 0, /* tp_alloc */
97 0, /* tp_new */
98 };
99
100 #if PY_MAJOR_VERSION >= 3
101 #define PY3K
102 #endif
103
104 static PyModuleDef embmodule =
105 {
106 PyModuleDef_HEAD_INIT,
107 "emb", 0, -1, 0,
108 };
109
110 // Internal state
111 PyObject* g_stdout;
112 PyObject* g_stdout_saved;
113
114 PyMODINIT_FUNC PyInit_emb(void)
115 {
116 g_stdout = 0;
117 g_stdout_saved = 0;
118
119 StdoutType.tp_new = PyType_GenericNew;
120 if (PyType_Ready(&StdoutType) < 0)
121 return 0;
122
123 PyObject* m = PyModule_Create(&embmodule);
124 if (m)
125 {
126 Py_INCREF(&StdoutType);
127 PyModule_AddObject(m, "Stdout", reinterpret_cast<PyObject*>(&StdoutType));
128 }
129 return m;
130 }
131
132 void set_stdout(stdout_write_type write)
133 {
134 if (!g_stdout)
135 {
136 g_stdout_saved = PySys_GetObject("stdout"); // borrowed
137 g_stdout = StdoutType.tp_new(&StdoutType, 0, 0);
138 }
139
140 Stdout* impl = reinterpret_cast<Stdout*>(g_stdout);
141 impl->write = write;
142 PySys_SetObject("stdout", g_stdout);
143 }
144
145 void reset_stdout()
146 {
147 if (g_stdout_saved)
148 PySys_SetObject("stdout", g_stdout_saved);
149
150 Py_XDECREF(g_stdout);
151 g_stdout = 0;
152 }
153
154 } // namespace emb
155
156 #endif