5 #include "flame/base.h"
8 #define PY_ARRAY_UNIQUE_SYMBOL FLAME_PyArray_API
9 #include <numpy/ndarrayobject.h>
13 #define FLAME_LOGGER_NAME "flame.machine"
17 struct PyLogger :
public Machine::Logger
20 virtual void log(
const Machine::LogRecord &r)
23 std::string msg(r.strm.str());
24 size_t pos = msg.find_last_not_of(
'\n');
26 msg = msg.substr(0, pos);
29 PyRef<> rec(PyObject_CallMethod(logger.py(),
"makeRecord",
"sHsHsOO",
30 FLAME_LOGGER_NAME, r.level, r.fname, r.lnum,
31 msg.c_str(), Py_None, Py_None));
32 PyRef<> junk(PyObject_CallMethod(logger.py(),
"handle",
"O", rec.py()));
35 static void noopdtor(Machine::Logger*) {}
38 singleton.logger.clear();
41 static PyLogger singleton;
44 PyLogger PyLogger::singleton;
47 PyObject* py_set_log(PyObject *unused, PyObject *args)
50 if(!PyArg_ParseTuple(args,
"H", &lvl))
53 Machine::log_detail = lvl;
58 PyObject* py_get_log(PyObject *unused)
60 return PyString_FromString(FLAME_LOGGER_NAME);
64 PyMethodDef modmethods[] = {
65 {
"_GLPSParse", (PyCFunction)&PyGLPSParse, METH_VARARGS|METH_KEYWORDS,
66 "Parse a GLPS lattice file to AST form"},
67 {
"GLPSPrinter", (PyCFunction)&PyGLPSPrint, METH_VARARGS,
68 "Print a dictionary in GLPS format to string"},
69 {
"setLogLevel", (PyCFunction)&py_set_log, METH_VARARGS,
70 "Set the FLAME logging level"
72 {
"getLoggerName", (PyCFunction)&py_get_log, METH_NOARGS,
73 "Returns the logger name used by the FLAME C extensions"
78 #if PY_MAJOR_VERSION >= 3
79 static struct PyModuleDef module = {
80 PyModuleDef_HEAD_INIT,
90 #if PY_MAJOR_VERSION >= 3
91 PyInit__internal(
void)
97 if (_import_array() < 0)
98 throw std::runtime_error(
"Failed to import numpy");
101 PyRef<> logging(PyImport_ImportModule(
"logging"));
102 PyLogger::singleton.logger.reset(PyObject_CallMethod(logging.py(),
"getLogger",
"s", FLAME_LOGGER_NAME));
103 if(Py_AtExit(&PyLogger::unreg)){
104 std::cerr<<
"Failed to add atexit PyLogger::unreg\n";
106 boost::shared_ptr<Machine::Logger> log(&PyLogger::singleton, &PyLogger::noopdtor);
107 Machine::set_logger(log);
109 }
catch(std::runtime_error& e){
110 std::cerr<<
"Failed to connect flame logging to python logging : "<<
typeid(e).name()<<
" : "<<e.what()<<
"\n";
113 #if PY_MAJOR_VERSION >= 3
115 PyRef<> modref(PyModule_Create(&module));
116 PyObject *mod = modref.py();
120 PyObject *mod = Py_InitModule(
"flame._internal", modmethods);
124 PyModule_AddIntConstant(mod,
"version", 0);
126 PyModule_AddIntConstant(mod,
"cversion", FLAME_API_VERSION);
128 PyModule_AddIntMacro(mod, FLAME_ERROR);
129 PyModule_AddIntMacro(mod, FLAME_WARN);
130 PyModule_AddIntMacro(mod, FLAME_INFO);
131 PyModule_AddIntMacro(mod, FLAME_DEBUG);
132 PyModule_AddIntMacro(mod, FLAME_FINE);
134 if(registerModMachine(mod))
135 throw std::runtime_error(
"Failed to initialize Machine");
136 if(registerModState(mod))
137 throw std::runtime_error(
"Failed to initialize State");
143 #if PY_MAJOR_VERSION >= 3
148 }CATCH2V(std::exception, RuntimeError)