#include #include #include #include "pythonmod.h" #include "../../paths.h" #define INIT() if (!initialized) init() #define WARNIF(x) if (x) xconf_notice("%s",#x); PYMODULE::PYMODULE(const char *_modname, PyObject *_ptbfe, PyObject *_pstrjoin) { initialized = 0; modname = strdup(_modname); pmod = NULL; pinst = NULL; psetmenu = NULL; pdomenu = NULL; pmessage = NULL; ptbfe = _ptbfe; pstrjoin = _pstrjoin; } PYMODULE::~PYMODULE() { free(modname); Py_XDECREF(pinst); Py_XDECREF(pmod); Py_XDECREF(psetmenu); Py_XDECREF(pdomenu); Py_XDECREF(pmessage); } bool PYMODULE::err() { bool ret = false; if (PyErr_Occurred() != NULL) { const char *tbinfo = ""; PyObject *ptype, *pvalue, *ptraceback, *ptbflist, *ptbinfo; PyErr_Fetch(&ptype,&pvalue,&ptraceback); ptbflist = PyEval_CallFunction(ptbfe,"OOO",ptype,pvalue,ptraceback); if (ptbflist != NULL) { ptbinfo = PyEval_CallFunction(pstrjoin,"Os",ptbflist,""); if (ptbinfo != NULL) tbinfo = PyString_AsString(ptbinfo); } xconf_error("pythonmod: an error occurred\n\n%s",tbinfo); PyErr_Clear(); ret = true; } return ret; } void PYMODULE::init() { pmod = PyImport_ImportModule(modname); if (!err()){ PyObject *pclass; pclass = PyObject_GetAttrString(pmod,"LinuxconfModule"); if (!err()) { pinst = PyEval_CallObject(pclass,NULL); if (!err()) { psetmenu = PyObject_GetAttrString(pinst,"setmenu"); pdomenu = PyObject_GetAttrString(pinst,"domenu"); pmessage = PyObject_GetAttrString(pinst, "message"); PyErr_Clear(); } Py_DECREF(pclass); } else { pinst = NULL; } } initialized = 1; } void PYMODULE::setmenu(DIALOG &dia, MENU_CONTEXT context) { INIT(); if (pinst != NULL) { if (psetmenu != NULL) { PyObject *pargs; pargs = Py_BuildValue("(Oi)",LCDialog_FromDialog(&dia),context); if (!err()) { PyObject *pres = PyEval_CallObject(psetmenu,pargs); err(); Py_DECREF(pargs); Py_XDECREF(pres); } } } } void PYMODULE::domenu(MENU_CONTEXT context, const char *keyword) { INIT(); if (pinst != NULL) { if (pdomenu != NULL) { PyObject *pargs; pargs = Py_BuildValue("(ii)",context,keyword); if (!err()) { PyObject *pres; pres = PyEval_CallObject(pdomenu,pargs); err(); Py_XDECREF(pres); Py_DECREF(pargs); } } } } int PYMODULE::execmain(int argc , char *argv[], bool standalone) { INIT(); int ret = LNCF_NOT_APPLICABLE; if (pinst != NULL) { PyObject *pexecmain = PyObject_GetAttrString(pinst, "execmain"); if (pexecmain != NULL) { PyObject *pargv = PyList_New(argc); if (err()) { Py_DECREF(pexecmain); return LNCF_NOT_APPLICABLE; } for (int i = 0; i != argc; i++) { PyList_SetItem(pargv,i,PyString_FromString(argv[i])); if (err()) { Py_DECREF(pexecmain); Py_DECREF(pargv); return LNCF_NOT_APPLICABLE; } } PyObject *pargs; pargs = Py_BuildValue("(Oi)",pargv,standalone?1:0); if (!err()) { PyObject *pres; pres = PyEval_CallObject(pexecmain,pargs); if (!err() && pres != Py_None) { ret = (int) PyInt_AsLong(pres); } Py_XDECREF(pres); Py_DECREF(pargs); } Py_DECREF(pexecmain); } else { PyErr_Clear(); } } return ret; } int PYMODULE::probe(int state, int target, bool simul) { INIT(); int ret = 0; if (pinst != NULL) { PyObject *pprobe = PyObject_GetAttrString(pinst, "probe"); if (pprobe != NULL) { PyObject *pargs; pargs = Py_BuildValue("(iii)",state,target,simul?1:0); if (!err()) { PyObject *pres; pres = PyEval_CallObject(pprobe,pargs); if (!err() && pres != Py_None) { ret = (int) PyInt_AsLong(pres); } Py_XDECREF(pres); Py_DECREF(pargs); } Py_DECREF(pprobe); } else { PyErr_Clear(); } } return ret; } int PYMODULE::message(const char *msg, int argc, const char *argv[]) { INIT(); int ret = LNCF_NOT_APPLICABLE; if (pinst != NULL) { if (pmessage != NULL) { PyObject *pargv = PyList_New(argc); if (err()) { Py_DECREF(pmessage); return LNCF_NOT_APPLICABLE; } for (int i = 0; i != argc; i++) { PyList_SetItem(pargv,i,LCMetaData_New((void*)argv[i])); if (err()) { Py_DECREF(pmessage); Py_DECREF(pargv); return LNCF_NOT_APPLICABLE; } } PyObject *pargs; pargs = Py_BuildValue("(sO)",msg,pargv); if (!err()) { PyObject *pres; pres = PyEval_CallObject(pmessage,pargs); if (!err() && pres != Py_None) { ret = (int) PyInt_AsLong(pres); } Py_XDECREF(pres); Py_DECREF(pargs); } } } return ret; } PYMODULES::PYMODULES() { initialized = 0; dirname = USR_LIB_LINUXCONF "/pythonmod"; } void PYMODULES::init() { setenv("PYTHONPATH",USR_LIB_LINUXCONF "/pythonmod:" USR_LIB_LINUXCONF "/pythonlib",1); Py_Initialize(); ptbmod = PyImport_ImportModule("traceback"); if (ptbmod == NULL) { xconf_error("pythonmod: can't import module 'traceback'"); return; } ptbfe = PyObject_GetAttrString(ptbmod, "format_exception"); if (ptbfe == NULL) { xconf_error("pythonmod: can't get 'format_exception' function"); return; } pstrmod = PyImport_ImportModule("string"); if (pstrmod == NULL) { xconf_error("pythonmod: can't import module 'string'"); return; } pstrjoin = PyObject_GetAttrString(pstrmod,"join"); if (pstrjoin == NULL) { xconf_error("pythonmod: can't get 'join' function"); return; } ok = true; readdir(dirname); initialized = 1; } PYMODULE* PYMODULES::getitem(int no) { return (PYMODULE*) ARRAY::getitem(no); } /* little redefinition of std::readdir() because gcc 2.7.2.1 knows nothing about std class (Miguel Angel Alvarez ) */ struct dirent * _readdir(DIR * dir) { return(readdir(dir)); } void PYMODULES::readdir(const char *dirname) { if (!ok) return; DIR *dir = opendir(dirname); if (dir == NULL) return; _readdir(dir); // Jump '.' _readdir(dir); // Jump '..' struct dirent *ent = _readdir(dir); while (ent != NULL) { char *ext = ent->d_name+(strlen(ent->d_name)-3); if (strcmp(ext,".py") == 0) { *ext = 0; PYMODULE *pym = new PYMODULE(ent->d_name, ptbfe, pstrjoin); this->add(pym); } ent = _readdir(dir); } closedir(dir); } #define FOREACH(x) \ { \ int nb = this->getnb(); \ for (int i = 0; i != nb; i++) { \ PYMODULE *pmod = this->getitem(i); \ x \ } \ } void PYMODULES::setmenu(DIALOG &dia, MENU_CONTEXT context) { INIT(); if (!ok) return; FOREACH(pmod->setmenu(dia,context);) } void PYMODULES::domenu(MENU_CONTEXT context, const char *keyword) { INIT(); if (!ok) return; FOREACH(pmod->domenu(context,keyword);) } int PYMODULES::execmain(int argc , char *argv[], bool standalone) { INIT(); if (!ok) return LNCF_NOT_APPLICABLE; int ret = LNCF_NOT_APPLICABLE; FOREACH(if((ret=pmod->execmain(argc,argv,standalone))!=LNCF_NOT_APPLICABLE) break;) return ret; } int PYMODULES::probe(int state, int target, bool simul) { INIT(); if (!ok) return LNCF_NOT_APPLICABLE; int ret = 0; FOREACH(if((ret=pmod->probe(state,target,simul))!=0) break;) return ret; } int PYMODULES::message(const char *msg, int argc, const char *argv[]) { INIT(); if (!ok) return LNCF_NOT_APPLICABLE; int ret = LNCF_NOT_APPLICABLE; FOREACH(if((ret=pmod->message(msg,argc,argv))!=LNCF_NOT_APPLICABLE) break;) return ret; } #if DEBUG int main() { PYMODULE pmod("module"); DIALOG dia; pmod.setmenu(dia,MENU_UNKNOWN); return 0; } #endif