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)