Mercurial > thymian
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 |
