5 #include "flame/base.h"
8 #define PY_ARRAY_UNIQUE_SYMBOL FLAME_PyArray_API
9 #define NPY_NO_DEPRECATED_API NPY_1_6_API_VERSION
10 #include <numpy/ndarrayobject.h>
14 #define FLAME_LOGGER_NAME "flame.machine"
18 struct PyLogger :
public Machine::Logger
21 virtual void log(
const Machine::LogRecord &r)
24 std::string msg(r.strm.str());
25 size_t pos = msg.find_last_not_of(
'\n');
27 msg = msg.substr(0, pos);
30 PyRef<> rec(PyObject_CallMethod(logger.py(),
"makeRecord",
"sHsHsOO",
31 FLAME_LOGGER_NAME, r.level, r.fname, r.lnum,
32 msg.c_str(), Py_None, Py_None));
33 PyRef<> junk(PyObject_CallMethod(logger.py(),
"handle",
"O", rec.py()));
36 static void noopdtor(Machine::Logger*) {}
39 singleton.logger.clear();
42 static PyLogger singleton;
45 PyLogger PyLogger::singleton;
48 PyObject* py_set_log(PyObject *unused, PyObject *args)
51 if(!PyArg_ParseTuple(args,
"H", &lvl))
54 Machine::log_detail = lvl;
59 PyObject* py_get_log(PyObject *unused)
61 return PyString_FromString(FLAME_LOGGER_NAME);
65 PyMethodDef modmethods[] = {
66 {
"_GLPSParse", (PyCFunction)&PyGLPSParse, METH_VARARGS|METH_KEYWORDS,
67 "Parse a GLPS lattice file to AST form"},
68 {
"GLPSPrinter", (PyCFunction)&PyGLPSPrint, METH_VARARGS,
69 "Print a dictionary in GLPS format to string"},
70 {
"setLogLevel", (PyCFunction)&py_set_log, METH_VARARGS,
71 "Set the FLAME logging level"
73 {
"getLoggerName", (PyCFunction)&py_get_log, METH_NOARGS,
74 "Returns the logger name used by the FLAME C extensions"
79 #if PY_MAJOR_VERSION >= 3
80 static struct PyModuleDef module = {
81 PyModuleDef_HEAD_INIT,
91 #if PY_MAJOR_VERSION >= 3
92 PyInit__internal(
void)
98 if (_import_array() < 0)
99 throw std::runtime_error(
"Failed to import numpy");
102 PyRef<> logging(PyImport_ImportModule(
"logging"));
103 PyLogger::singleton.logger.reset(PyObject_CallMethod(logging.py(),
"getLogger",
"s", FLAME_LOGGER_NAME));
104 if(Py_AtExit(&PyLogger::unreg)){
105 std::cerr<<
"Failed to add atexit PyLogger::unreg\n";
107 boost::shared_ptr<Machine::Logger> log(&PyLogger::singleton, &PyLogger::noopdtor);
108 Machine::set_logger(log);
110 }
catch(std::runtime_error& e){
111 std::cerr<<
"Failed to connect flame logging to python logging : "<<
typeid(e).name()<<
" : "<<e.what()<<
"\n";
114 #if PY_MAJOR_VERSION >= 3
116 PyRef<> modref(PyModule_Create(&module));
117 PyObject *mod = modref.py();
121 PyObject *mod = Py_InitModule(
"flame._internal", modmethods);
125 PyModule_AddIntConstant(mod,
"_pyapi_version", 0);
127 PyModule_AddIntConstant(mod,
"_capi_version", FLAME_API_VERSION);
129 PyModule_AddIntMacro(mod, FLAME_ERROR);
130 PyModule_AddIntMacro(mod, FLAME_WARN);
131 PyModule_AddIntMacro(mod, FLAME_INFO);
132 PyModule_AddIntMacro(mod, FLAME_DEBUG);
133 PyModule_AddIntMacro(mod, FLAME_FINE);
135 if(registerModMachine(mod))
136 throw std::runtime_error(
"Failed to initialize Machine");
137 if(registerModState(mod))
138 throw std::runtime_error(
"Failed to initialize State");
144 #if PY_MAJOR_VERSION >= 3
149 }CATCH2V(std::exception, RuntimeError)