-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathpythonlib.cpp
More file actions
90 lines (73 loc) · 1.88 KB
/
pythonlib.cpp
File metadata and controls
90 lines (73 loc) · 1.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <iostream>
#include <vector>
#include <sstream>
#include <Python.h>
#include "ccc.h"
char CCC_BASENAME[] = "ccc";
static PyObject* ccc(PyObject* self, PyObject* args) {
// The ccc function takes a list of arguments, we first need to pull
// the list out of the args tuple
PyObject* argList;
if(!PyArg_ParseTuple(args, "O", &argList)) {
return nullptr;
}
auto argc = static_cast<int>(PyList_Size(argList));
if(argc < 0) {
return nullptr;
}
std::vector<const char*> argv;
argv.reserve(argc+1);
argv.push_back(CCC_BASENAME);
for (int i = 0; i < argc; ++i) {
auto item = PyList_GetItem(argList, i);
if (!item) {
return nullptr;
}
auto argument = PyUnicode_AsUTF8(item);
if (!argument) {
return nullptr;
}
argv.push_back(argument);
}
std::stringstream buffer;
std::streambuf* old_cout = std::cout.rdbuf(buffer.rdbuf());
std::streambuf* old_cerr = std::cerr.rdbuf(buffer.rdbuf());
int return_value = run(argc + 1, argv.data());
std::cout.rdbuf(old_cout);
std::cerr.rdbuf(old_cerr);
std::string compilation_log = buffer.str();
return Py_BuildValue("(is)", return_value, compilation_log.c_str());
}
static PyMethodDef ccscript_methods[] = {
{"ccc", ccc, METH_VARARGS, "ccc"},
{NULL, NULL, 0, NULL}
};
struct module_state {
PyObject *error;
};
#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
static int ccscript_traverse(PyObject *m, visitproc visit, void *arg) {
Py_VISIT(GETSTATE(m)->error);
return 0;
}
static int ccscript_clear(PyObject *m) {
Py_CLEAR(GETSTATE(m)->error);
return 0;
}
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT,
"ccscript",
NULL,
sizeof(struct module_state),
ccscript_methods,
NULL,
ccscript_traverse,
ccscript_clear,
NULL
};
PyMODINIT_FUNC
PyInit_ccscript(void)
{
PyObject *module = PyModule_Create(&moduledef);
return module;
}