From 2fc65e1012a9afea5e40c8a5004acbd624139318 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Fri, 16 Feb 2007 10:45:24 +0000 Subject: [PATCH] fixes compilation problems related to sip4 (Python/C++ binding generator). The version included is 4.1.1. If you generate some files using a new version of sip4, update or remove sip.h in the apps/py_sems/sip directory. git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@231 8eb893ce-cfd4-0310-b710-fb5ebe64c474 --- apps/py_sems/Ivr.cpp | 598 -------------------------------------- apps/py_sems/Ivr.h | 128 -------- apps/py_sems/IvrAudio.cpp | 321 -------------------- apps/py_sems/IvrAudio.h | 33 --- apps/py_sems/Makefile | 4 +- apps/py_sems/PySems.cpp | 1 - apps/py_sems/sip/sip.h | 560 +++++++++++++++++++++++++++++++++++ 7 files changed, 562 insertions(+), 1083 deletions(-) delete mode 100644 apps/py_sems/Ivr.cpp delete mode 100644 apps/py_sems/Ivr.h delete mode 100644 apps/py_sems/IvrAudio.cpp delete mode 100644 apps/py_sems/IvrAudio.h create mode 100644 apps/py_sems/sip/sip.h diff --git a/apps/py_sems/Ivr.cpp b/apps/py_sems/Ivr.cpp deleted file mode 100644 index 09b551ff..00000000 --- a/apps/py_sems/Ivr.cpp +++ /dev/null @@ -1,598 +0,0 @@ -/* - * $Id: Ivr.cpp,v 1.26.2.1 2005/09/02 13:47:46 rco Exp $ - * Copyright (C) 2002-2003 Fhg Fokus - * - * This file is part of sems, a free SIP media server. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -//#include "IvrDialogBase.h" -//#include "IvrSipDialog.h" -#include "IvrAudio.h" -#include "Ivr.h" - -#include "AmConfigReader.h" -#include "AmConfig.h" -#include "log.h" -#include "AmApi.h" -#include "AmUtils.h" -#include "AmSessionScheduler.h" -//#include "AmSessionTimer.h" -#include "AmPlugIn.h" - -#include "sip/sipAPIpy_ivr.h" -#include "sip/sippy_ivrIvrDialog.h" - -#include -#include -#include -#include - -#include -using std::set; - - -#define PYFILE_REGEX "(.+)\\.(py|pyc|pyo)$" - - -EXPORT_SESSION_FACTORY(IvrFactory,MOD_NAME); - -PyMODINIT_FUNC initpy_ivr(); - -struct PythonGIL -{ - PyGILState_STATE gst; - - PythonGIL() { gst = PyGILState_Ensure(); } - ~PythonGIL(){ PyGILState_Release(gst); } -}; - - -// This must be the first declaration of every -// function using Python C-API. -// But this is not necessary in function which -// will get called from Python -#define PYLOCK PythonGIL _py_gil - -extern "C" { - - static PyObject* ivr_log(PyObject*, PyObject* args) - { - int level; - char *msg; - - if(!PyArg_ParseTuple(args,"is",&level,&msg)) - return NULL; - - if((level)<=log_level) { - - //if(level == L_ERR) - //assert(0); - - if(log_stderr) - log_print( level, msg ); - else { - switch(level){ - case L_ERR: - syslog(LOG_ERR | L_FAC, "Error: %s", msg); - break; - case L_WARN: - syslog(LOG_WARNING | L_FAC, "Warning: %s", msg); - break; - case L_INFO: - syslog(LOG_INFO | L_FAC, "Info: %s", msg); - break; - case L_DBG: - syslog(LOG_DEBUG | L_FAC, "Debug: %s", msg); - break; - } - } - } - - Py_INCREF(Py_None); - return Py_None; - } - - static PyObject* ivr_getHeader(PyObject*, PyObject* args) - { - char* headers; - char* header_name; - if(!PyArg_ParseTuple(args,"ss",&headers,&header_name)) - return NULL; - - string res = getHeader(headers,header_name); - return PyString_FromString(res.c_str()); - } - - - static PyMethodDef ivr_methods[] = { - {"log", (PyCFunction)ivr_log, METH_VARARGS,"Log a message using Sems' logging system"}, - {"getHeader", (PyCFunction)ivr_getHeader, METH_VARARGS,"Python getHeader wrapper"}, - {NULL} /* Sentinel */ - }; -} - -IvrFactory::IvrFactory(const string& _app_name) - : AmSessionFactory(_app_name), - user_timer_fact(NULL) -{ -} - -void IvrFactory::setScriptPath(const string& path) -{ - string python_path = script_path = path; - - - if(python_path.length()){ - - python_path = AmConfig::PlugInPath + ":" + python_path; - } - else - python_path = AmConfig::PlugInPath; - - char* old_path=0; - if((old_path = getenv("PYTHONPATH")) != 0) - if(strlen(old_path)) - python_path += ":" + string(old_path); - - DBG("setting PYTHONPATH to: '%s'\n",python_path.c_str()); - setenv("PYTHONPATH",python_path.c_str(),1); - -} - -void IvrFactory::import_object(PyObject* m, char* name, PyTypeObject* type) -{ - if (PyType_Ready(type) < 0){ - ERROR("PyType_Ready failed !\n"); - return; - } - Py_INCREF(type); - PyModule_AddObject(m, name, (PyObject *)type); -} - -void IvrFactory::import_ivr_builtins() -{ - // ivr module - start - PyImport_AddModule("ivr"); - ivr_module = Py_InitModule("ivr",ivr_methods); - - // IvrSipDialog (= AmSipDialog) - //import_object(ivr_module, "IvrSipDialog", &IvrSipDialogType); - - // IvrDialogBase - //import_object(ivr_module,"IvrDialogBase",&IvrDialogBaseType); - - - // IvrAudioFile - import_object(ivr_module,"IvrAudioFile",&IvrAudioFileType); - - PyModule_AddIntConstant(ivr_module, "AUDIO_READ",AUDIO_READ); - PyModule_AddIntConstant(ivr_module, "AUDIO_WRITE",AUDIO_WRITE); - // ivr module - end - - // add log level for the log module - PyModule_AddIntConstant(ivr_module, "SEMS_LOG_LEVEL",log_level); - - import_module("log"); - initpy_ivr(); -} - -void IvrFactory::import_module(const char* modname) -{ - PyObject* py_mod_name = PyString_FromString(modname); - PyObject* py_mod = PyImport_Import(py_mod_name); - Py_DECREF(py_mod_name); - - if(!py_mod){ - PyErr_Print(); - ERROR("IvrFactory: could not find python module '%s'.\n",modname); - ERROR("IvrFactory: please check your installation.\n"); - return; - } -} - -void IvrFactory::init_python_interpreter() -{ - Py_Initialize(); - PyEval_InitThreads(); - import_ivr_builtins(); - PyEval_ReleaseLock(); -} - -IvrDialog* IvrFactory::newDlg(const string& name) -{ - PYLOCK; - - map::iterator mod_it = mod_reg.find(name); - if(mod_it == mod_reg.end()){ - ERROR("Unknown script name '%s'\n", name.c_str()); - throw AmSession::Exception(500,"Unknown Application"); - } - - IvrScriptDesc& mod_desc = mod_it->second; - - AmDynInvoke* user_timer = user_timer_fact->getInstance(); - if(!user_timer){ - ERROR("could not get a user timer reference\n"); - throw AmSession::Exception(500,"could not get a user timer reference"); - } - - PyObject* dlg_inst = PyObject_Call(mod_desc.dlg_class,PyTuple_New(0),NULL); - if(!dlg_inst){ - - PyErr_Print(); - ERROR("IvrFactory: while loading \"%s\": could not create instance\n", - name.c_str()); - throw AmSession::Exception(500,"Internal error in IVR plug-in."); - - return NULL; - } - - int err=0; - IvrDialog* dlg = (IvrDialog*)sipForceConvertTo_IvrDialog(dlg_inst,&err); - if(!dlg || err){ - - PyErr_Print(); - ERROR("IvrFactory: while loading \"%s\": could not retrieve IvrDialog ptr.\n", - name.c_str()); - throw AmSession::Exception(500,"Internal error in IVR plug-in."); - Py_DECREF(dlg_inst); - - return NULL; - } - - // take the ownership over dlg - sipTransfer(dlg_inst,1); - - return dlg; -} - -bool IvrFactory::loadScript(const string& path) -{ - PYLOCK; - - PyObject *modName,*mod,*dict, *dlg_class, *config=NULL; - - modName = PyString_FromString(path.c_str()); - mod = PyImport_Import(modName); - - AmConfigReader cfg; - string cfg_file = add2path(AmConfig::ModConfigPath,1,(path + ".conf").c_str()); - - Py_DECREF(modName); - - if(!mod){ - PyErr_Print(); - WARN("IvrFactory: Failed to load \"%s\"\n", path.c_str()); - - dict = PyImport_GetModuleDict(); - Py_INCREF(dict); - PyDict_DelItemString(dict,path.c_str()); - Py_DECREF(dict); - - return false; - } - - dict = PyModule_GetDict(mod); - dlg_class = PyDict_GetItemString(dict, "IvrScript"); - - if(!dlg_class){ - - PyErr_Print(); - WARN("IvrFactory: class IvrDialog not found in \"%s\"\n", path.c_str()); - goto error1; - } - - Py_INCREF(dlg_class); - - if(!PyObject_IsSubclass(dlg_class,(PyObject *)sipClass_IvrDialog)){ - - WARN("IvrFactory: in \"%s\": IvrScript is not a " - "subtype of IvrDialog\n", path.c_str()); - - goto error2; - } - - if(cfg.loadFile(cfg_file)){ - ERROR("could not load config file at %s\n",cfg_file.c_str()); - goto error2; - } - - config = PyDict_New(); - if(!config){ - ERROR("could not allocate new dict for config\n"); - goto error2; - } - - for(map::const_iterator it = cfg.begin(); - it != cfg.end(); it++){ - - PyDict_SetItem(config, - PyString_FromString(it->first.c_str()), - PyString_FromString(it->second.c_str())); - } - - PyObject_SetAttrString(mod,"config",config); - - mod_reg.insert(make_pair(path, - IvrScriptDesc(mod,dlg_class))); - - return true; - - error2: - Py_DECREF(dlg_class); - error1: - Py_DECREF(mod); - - return false; -} - -/** - * Loads python script path and default script file from configuration file - */ -int IvrFactory::onLoad() -{ - user_timer_fact = AmPlugIn::instance()->getFactory4Di("user_timer"); - if(!user_timer_fact){ - - ERROR("could not load user_timer from session_timer plug-in\n"); - return -1; - } - - - AmConfigReader cfg; - - if(cfg.loadFile(add2path(AmConfig::ModConfigPath,1,MOD_NAME ".conf"))) - return -1; - - // get application specific global parameters - configureModule(cfg); - - setScriptPath(cfg.getParameter("script_path")); - init_python_interpreter(); - - DBG("** IVR compile time configuration:\n"); - DBG("** built with PYTHON support.\n"); - -#ifdef IVR_WITH_TTS - DBG("** Text-To-Speech enabled\n"); -#else - DBG("** Text-To-Speech disabled\n"); -#endif - - DBG("** IVR run time configuration:\n"); - DBG("** script path: \'%s\'\n", script_path.c_str()); - - regex_t reg; - if(regcomp(®,PYFILE_REGEX,REG_EXTENDED)){ - ERROR("while compiling regular expression\n"); - return -1; - } - - DIR* dir = opendir(script_path.c_str()); - if(!dir){ - regfree(®); - ERROR("Ivr: script pre-loader (%s): %s\n", - script_path.c_str(),strerror(errno)); - return -1; - } - - DBG("directory '%s' opened\n",script_path.c_str()); - - set unique_entries; - regmatch_t pmatch[2]; - - struct dirent* entry=0; - while((entry = readdir(dir)) != NULL){ - - if(!regexec(®,entry->d_name,2,pmatch,0)){ - - string name(entry->d_name + pmatch[1].rm_so, - pmatch[1].rm_eo - pmatch[1].rm_so); - - unique_entries.insert(name); - } - } - closedir(dir); - regfree(®); - - AmPlugIn* plugin = AmPlugIn::instance(); - for(set::iterator it = unique_entries.begin(); - it != unique_entries.end(); it++) { - - if(loadScript(*it)){ - bool res = plugin->registerFactory4App(*it,this); - if(res) - INFO("Application script registered: %s.\n", - it->c_str()); - } - } - - return 0; // don't stop sems from starting up -} - -/** - * Load a script using user name from URI. - * Note: there is no default script. - */ -AmSession* IvrFactory::onInvite(const AmSipRequest& req) -{ - if(req.cmd != MOD_NAME) - return newDlg(req.cmd); - else - return newDlg(req.user); -} - -IvrDialog::IvrDialog() - : py_mod(NULL), - py_dlg(NULL), - playlist(this), - user_timer(NULL) -{ - sip_relay_only = false; -} - -IvrDialog::IvrDialog(AmDynInvoke* user_timer) - : py_mod(NULL), - py_dlg(NULL), - playlist(this), - user_timer(user_timer) -{ - sip_relay_only = false; -} - -IvrDialog::~IvrDialog() -{ - DBG("IvrDialog::~IvrDialog()\n"); - - PYLOCK; - Py_XDECREF(py_mod); - Py_XDECREF(py_dlg); -} - -void IvrDialog::setPyPtrs(PyObject *mod, PyObject *dlg) -{ - assert(py_mod = mod); - assert(py_dlg = dlg); - Py_INCREF(py_mod); - Py_INCREF(py_dlg); -} - -static PyObject * -type_error(const char *msg) -{ - PyErr_SetString(PyExc_TypeError, msg); - return NULL; -} - -static PyObject * -null_error(void) -{ - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_SystemError, - "null argument to internal routine"); - return NULL; -} - -PyObject * -PyObject_VaCallMethod(PyObject *o, char *name, char *format, va_list va) -{ - PyObject *args, *func = 0, *retval; - - if (o == NULL || name == NULL) - return null_error(); - - func = PyObject_GetAttrString(o, name); - if (func == NULL) { - PyErr_SetString(PyExc_AttributeError, name); - return 0; - } - - if (!PyCallable_Check(func)) - return type_error("call of non-callable attribute"); - - if (format && *format) { - args = Py_VaBuildValue(format, va); - } - else - args = PyTuple_New(0); - - if (!args) - return NULL; - - if (!PyTuple_Check(args)) { - PyObject *a; - - a = PyTuple_New(1); - if (a == NULL) - return NULL; - if (PyTuple_SetItem(a, 0, args) < 0) - return NULL; - args = a; - } - - retval = PyObject_Call(func, args, NULL); - - Py_DECREF(args); - Py_DECREF(func); - - return retval; -} - -bool IvrDialog::callPyEventHandler(char* name, char* fmt, ...) -{ - bool ret=false; - va_list va; - - PYLOCK; - - va_start(va, fmt); - PyObject* o = PyObject_VaCallMethod(py_dlg,name,fmt,va); - va_end(va); - - if(!o) { - - if(PyErr_ExceptionMatches(PyExc_AttributeError)){ - - DBG("method %s is not implemented, trying default one\n",name); - return true; - } - - PyErr_Print(); - } - else { - if(o && PyBool_Check(o) && (o == Py_True)) { - - ret = true; - } - - Py_DECREF(o); - } - - return ret; -} - -void IvrDialog::onSessionStart(const AmSipRequest& req) -{ - DBG("IvrDialog::onSessionStart\n"); - setInOut(&playlist,&playlist); - AmB2BCallerSession::onSessionStart(req); -} - -void IvrDialog::process(AmEvent* event) -{ - DBG("IvrDialog::process\n"); - - AmAudioEvent* audio_event = dynamic_cast(event); - if(audio_event && audio_event->event_id == AmAudioEvent::noAudio){ - - callPyEventHandler("onEmptyQueue", NULL); - event->processed = true; - } - - AmPluginEvent* plugin_event = dynamic_cast(event); - if(plugin_event && plugin_event->name == "timer_timeout") { - - callPyEventHandler("onTimer", "i", plugin_event->data.get(0).asInt()); - event->processed = true; - } - - if (!event->processed) - AmB2BCallerSession::process(event); - - return; -} - diff --git a/apps/py_sems/Ivr.h b/apps/py_sems/Ivr.h deleted file mode 100644 index 2d229704..00000000 --- a/apps/py_sems/Ivr.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * $Id: Ivr.h,v 1.15.2.1 2005/09/02 13:47:46 rco Exp $ - * Copyright (C) 2002-2003 Fhg Fokus - * - * This file is part of sems, a free SIP media server. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _IVR_H_ -#define _IVR_H_ - -#define MOD_NAME "ivr" - -#include - -#include "AmB2BSession.h" -#include "AmPlaylist.h" - -#ifdef IVR_WITH_TTS -#include "flite.h" -#endif - -#include -#include -using std::string; -using std::map; - -class IvrDialog; - -struct IvrScriptDesc -{ - PyObject* mod; - PyObject* dlg_class; - - IvrScriptDesc() - : mod(0), - dlg_class(0) - {} - - IvrScriptDesc(const IvrScriptDesc& d) - : mod(d.mod), - dlg_class(d.dlg_class) - {} - - IvrScriptDesc(PyObject* mod, - PyObject* dlg_class) - : mod(mod), - dlg_class(dlg_class) - {} -}; - - -class IvrFactory: public AmSessionFactory -{ - PyObject* ivr_module; - string script_path; - string default_script; - - map mod_reg; - - AmDynInvokeFactory* user_timer_fact; - - void init_python_interpreter(); - void import_ivr_builtins(); - - void import_module(const char* modname); - void import_object(PyObject* m, - char* name, - PyTypeObject* type); - - /** @return true if everything ok */ - bool loadScript(const string& path); - - void setScriptPath(const string& path); - bool checkCfg(); - - IvrDialog* newDlg(const string& name); - - public: - IvrFactory(const string& _app_name); - - int onLoad(); - AmSession* onInvite(const AmSipRequest& req); -}; - - -class IvrDialog : public AmB2BCallerSession -{ - PyObject *py_mod; - PyObject *py_dlg; - - bool callPyEventHandler(char* name, char* fmt, ...); - - void process(AmEvent* event); - -public: - AmDynInvoke* user_timer; - AmPlaylist playlist; - - IvrDialog(); - IvrDialog(AmDynInvoke* user_timer); - ~IvrDialog(); - - // must be called before everything else. - void setPyPtrs(PyObject *mod, PyObject *dlg); - - void onSessionStart(const AmSipRequest& req); -/* void onBye(const AmSipRequest& req); */ -/* void onDtmf(int event, int duration_msec); */ - -/* void onOtherBye(const AmSipRequest& req); */ -/* void onOtherReply(const AmSipReply& r); */ -}; - -#endif diff --git a/apps/py_sems/IvrAudio.cpp b/apps/py_sems/IvrAudio.cpp deleted file mode 100644 index e7d18e56..00000000 --- a/apps/py_sems/IvrAudio.cpp +++ /dev/null @@ -1,321 +0,0 @@ -#include "IvrAudio.h" -#include "AmAudio.h" -#include "AmSession.h" - -#include "log.h" - -#ifdef IVR_WITH_TTS - -#define TTS_CACHE_PATH "/tmp/" -extern "C" cst_voice *register_cmu_us_kal(); - -#endif //ivr_with_tts - - -static PyObject* IvrAudioFile_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - DBG("---------- IvrAudioFile_alloc -----------\n"); - IvrAudioFile *self; - - self = (IvrAudioFile *)type->tp_alloc(type, 0); - - if (self != NULL) { - - self->af = new AmAudioFile(); - if(!self->af){ - Py_DECREF(self); - return NULL; - } - -#ifdef IVR_WITH_TTS - flite_init(); - self->tts_voice = register_cmu_us_kal(); - self->filename = new string(); -#endif - - } - - return (PyObject *)self; -} - -static void IvrAudioFile_dealloc(IvrAudioFile* self) -{ - DBG("---------- IvrAudioFile_dealloc -----------\n"); - delete self->af; - self->af = NULL; - -#ifdef IVR_WITH_TTS - if(self->del_file && !self->filename->empty()) - unlink(self->filename->c_str()); - delete self->filename; -#endif - - self->ob_type->tp_free((PyObject*)self); -} - -static PyObject* IvrAudioFile_open(IvrAudioFile* self, PyObject* args) -{ - int ivr_open_mode; - char* filename; - bool is_tmp; - PyObject* py_is_tmp = NULL; - AmAudioFile::OpenMode open_mode; - - if(!PyArg_ParseTuple(args,"si|O",&filename,&ivr_open_mode,&py_is_tmp)) - return NULL; - - switch(ivr_open_mode){ - case AUDIO_READ: - open_mode = AmAudioFile::Read; - break; - case AUDIO_WRITE: - open_mode = AmAudioFile::Write; - break; - default: - PyErr_SetString(PyExc_TypeError,"Unknown open mode"); - return NULL; - break; - } - - if((py_is_tmp == NULL) || (py_is_tmp == Py_False)) - is_tmp = false; - else if(py_is_tmp == Py_True) - is_tmp = true; - else { - PyErr_SetString(PyExc_TypeError,"third parameter should be of type PyBool"); - return NULL; - } - - if(self->af->open(filename,open_mode,is_tmp)){ - PyErr_SetString(PyExc_IOError,"Could not open file"); - return NULL; - } - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* IvrAudioFile_fpopen(IvrAudioFile* self, PyObject* args) -{ - int ivr_open_mode; - char* filename; - PyObject* py_file = NULL; - AmAudioFile::OpenMode open_mode; - - if(!PyArg_ParseTuple(args,"siO",&filename,&ivr_open_mode,&py_file)) - return NULL; - - switch(ivr_open_mode){ - case AUDIO_READ: - open_mode = AmAudioFile::Read; - break; - case AUDIO_WRITE: - open_mode = AmAudioFile::Write; - break; - default: - PyErr_SetString(PyExc_TypeError,"Unknown open mode"); - return NULL; - break; - } - - FILE* fp = PyFile_AsFile(py_file); - if(!fp){ - PyErr_SetString(PyExc_IOError,"Could not get FILE pointer"); - return NULL; - } - - if(self->af->fpopen(filename,open_mode,fp)){ - PyErr_SetString(PyExc_IOError,"Could not open file"); - return NULL; - } - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* IvrAudioFile_rewind(IvrAudioFile* self, PyObject* args) -{ - self->af->rewind(); - Py_INCREF(Py_None); - return Py_None; -} - -#ifdef IVR_WITH_TTS -static PyObject* IvrAudioFile_tts(PyObject* cls, PyObject* args) -{ - char* text; - if(!PyArg_ParseTuple(args,"s",&text)) - return NULL; - - PyObject* constr_args = Py_BuildValue("(O)",Py_None); - PyObject* tts_file = PyObject_CallObject(cls,constr_args); - Py_DECREF(constr_args); - - if(tts_file == NULL){ - PyErr_Print(); - PyErr_SetString(PyExc_RuntimeError,"could not create new IvrAudioFile object"); - return NULL; - } - - IvrAudioFile* self = (IvrAudioFile*)tts_file; - - *self->filename = string(TTS_CACHE_PATH) + AmSession::getNewId() + string(".wav"); - self->del_file = true; - flite_text_to_speech(text,self->tts_voice,self->filename->c_str()); - - if(self->af->open(self->filename->c_str(),AmAudioFile::Read)){ - Py_DECREF(tts_file); - PyErr_SetString(PyExc_IOError,"could not open TTS file"); - return NULL; - } - - return tts_file; -} -#endif - -static PyObject* IvrAudioFile_close(IvrAudioFile* self, PyObject*) -{ - self->af->close(); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* IvrAudioFile_getDataSize(IvrAudioFile* self, PyObject*) -{ - return PyInt_FromLong(self->af->getDataSize()); -} - -static PyObject* IvrAudioFile_setRecordTime(IvrAudioFile* self, PyObject* args) -{ - int rec_time; - if(!PyArg_ParseTuple(args,"i",&rec_time)) - return NULL; - - self->af->setRecordTime(rec_time); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* IvrAudioFile_exportRaw(IvrAudioFile* self, PyObject*) -{ - if(self->af->getMode() == AmAudioFile::Write) - self->af->on_close(); - - self->af->rewind(); - - return PyFile_FromFile(self->af->getfp(),"","rwb",NULL); -} - - -static PyMethodDef IvrAudioFile_methods[] = { - {"open", (PyCFunction)IvrAudioFile_open, METH_VARARGS, - "open the audio file" - }, - {"fpopen", (PyCFunction)IvrAudioFile_fpopen, METH_VARARGS, - "open the audio file" - }, - {"close", (PyCFunction)IvrAudioFile_close, METH_NOARGS, - "close the audio file" - }, - {"rewind", (PyCFunction)IvrAudioFile_rewind, METH_NOARGS, - "rewind the audio file" - }, - {"getDataSize", (PyCFunction)IvrAudioFile_getDataSize, METH_NOARGS, - "returns the recorded data size" - }, - {"setRecordTime", (PyCFunction)IvrAudioFile_setRecordTime, METH_VARARGS, - "set the maximum record time in millisecond" - }, - {"exportRaw", (PyCFunction)IvrAudioFile_exportRaw, METH_NOARGS, - "creates a new Python file with the actual file" - " and eventually flushes headers (audio->on_stop)" - }, -#ifdef IVR_WITH_TTS - {"tts", (PyCFunction)IvrAudioFile_tts, METH_CLASS | METH_VARARGS, - "text to speech" - }, -#endif - {NULL} /* Sentinel */ -}; - - -static PyObject* IvrAudioFile_getloop(IvrAudioFile* self, void*) -{ - PyObject* loop = self->af->loop.get() ? Py_True : Py_False; - Py_INCREF(loop); - return loop; -} - -static int IvrAudioFile_setloop(IvrAudioFile* self, PyObject* value, void*) -{ - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute"); - return -1; - } - - if(value == Py_True) - self->af->loop.set(true); - - else if(value == Py_False) - self->af->loop.set(false); - - else { - PyErr_SetString(PyExc_TypeError, - "The first attribute value must be a boolean"); - return -1; - } - - return 0; -} - -static PyGetSetDef IvrAudioFile_getseters[] = { - {"loop", - (getter)IvrAudioFile_getloop, (setter)IvrAudioFile_setloop, - "repeat mode", - NULL}, - {NULL} /* Sentinel */ -}; - -PyTypeObject IvrAudioFileType = { - - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - "ivr.IvrAudioFile", /*tp_name*/ - sizeof(IvrAudioFile), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)IvrAudioFile_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - "An audio file", /*tp_doc*/ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - IvrAudioFile_methods, /* tp_methods */ - 0, /* tp_members */ - IvrAudioFile_getseters, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - IvrAudioFile_new, /* tp_new */ -}; diff --git a/apps/py_sems/IvrAudio.h b/apps/py_sems/IvrAudio.h deleted file mode 100644 index fa73f4ff..00000000 --- a/apps/py_sems/IvrAudio.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef IvrAudio_h -#define IvrAudio_h - -// Python stuff -#include -#include "structmember.h" - -#include "AmAudio.h" - -#define AUDIO_READ 1 -#define AUDIO_WRITE 2 - -#ifdef IVR_WITH_TTS -#include "flite.h" -#endif - -// Data definition -typedef struct { - - PyObject_HEAD - AmAudioFile* af; - -#ifdef IVR_WITH_TTS - cst_voice* tts_voice; - string* filename; - bool del_file; -#endif - -} IvrAudioFile; - -extern PyTypeObject IvrAudioFileType; - -#endif diff --git a/apps/py_sems/Makefile b/apps/py_sems/Makefile index 6cbd05c1..1b7754b5 100644 --- a/apps/py_sems/Makefile +++ b/apps/py_sems/Makefile @@ -3,7 +3,7 @@ plug_in_name = py_sems COREPATH ?=../../core SCRIPT = Python -TTS = y +TTS ?= y # # Python specific @@ -25,7 +25,7 @@ PYTHON_LIBDIR = $(PYTHON_PREFIX)/lib/python$(PY_VER) # put used Python modules from lib-dynload here, e.g. time, mysql, _cvs.so etc. PYTHON_DYNLOAD_MODULES = $(wildcard $(PYTHON_LIBDIR)/lib-dynload/*.so) \ $(wildcard $(PYTHON_LIBDIR)/site-packages/*.so) -PYTHON_module_cflags = -I$(PYTHON_DIR) +PYTHON_module_cflags = -I$(PYTHON_DIR) -Isip/ PYTHON_module_ldflags = -Xlinker --export-dynamic \ -L$(PYTHON_LIBDIR)/config \ -lpython$(PY_VER) $(wildcard sip/*.o) diff --git a/apps/py_sems/PySems.cpp b/apps/py_sems/PySems.cpp index 9a0c7af0..92794cda 100644 --- a/apps/py_sems/PySems.cpp +++ b/apps/py_sems/PySems.cpp @@ -27,7 +27,6 @@ #include "log.h" #include "AmApi.h" #include "AmUtils.h" -#include "AmMediaProcessor.h" #include "AmPlugIn.h" #include "sip/sipAPIpy_sems_lib.h" diff --git a/apps/py_sems/sip/sip.h b/apps/py_sems/sip/sip.h new file mode 100644 index 00000000..0bba8909 --- /dev/null +++ b/apps/py_sems/sip/sip.h @@ -0,0 +1,560 @@ +/* + * The SIP module interface. + * + * Copyright (c) 2004 + * Riverbank Computing Limited + * + * This file is part of SIP. + * + * This copy of SIP is licensed for use under the terms of the SIP License + * Agreement. See the file LICENSE for more details. + * + * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + + +#ifndef _SIP_H +#define _SIP_H + + +#include + +/* + * There is a mis-feature somewhere with the Borland compiler. This works + * around it. + */ +#if defined(__BORLANDC__) +#include +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Sanity check on the Python version. */ +#if PY_VERSION_HEX < 0x02030000 +#error "This version of SIP requires Python v2.3 or later" +#endif + + +/* + * Define the SIP version number. + */ +#define SIP_VERSION 0x040101 +#define SIP_VERSION_STR "4.1.1" +#define SIP_BUILD "255" + + +/* + * Define the current API version number. SIP must handle modules with the + * same major number and with the same or earlier minor number. Whenever data + * structure elements are added they must be appended and the minor number + * incremented. Whenever data structure elements are removed or the order + * changed then the major number must be incremented and the minor number set + * to 0. + * + * History: + * + * 0.2 Added the 'H' format character to sip_api_parse_args(). + * + * 0.1 Added sip_api_add_class_instance(). + * Added the 't' format character to sip_api_parse_args(). + * Deprecated the 'J' and 'K' format characters to sip_api_parse_result(). + * + * 0.0 Original version. + */ +#define SIP_API_MAJOR_NR 0 +#define SIP_API_MINOR_NR 2 + + +/* Some compatibility stuff to help with handwritten code for SIP v3. */ +#if !defined(ANY) +#define ANY void +#endif + + +/* + * The mask that can be passed to sipTrace(). + */ +#define SIP_TRACE_CATCHERS 0x0001 +#define SIP_TRACE_CTORS 0x0002 +#define SIP_TRACE_DTORS 0x0004 +#define SIP_TRACE_INITS 0x0008 +#define SIP_TRACE_DEALLOCS 0x0010 +#define SIP_TRACE_METHODS 0x0020 + + +/* + * Hide some thread dependent stuff. + */ +#ifdef WITH_THREAD +typedef PyGILState_STATE sip_gilstate_t; +#define SIP_RELEASE_GIL(gs) PyGILState_Release(gs); +#define SIP_BLOCK_THREADS {PyGILState_STATE sipGIL = PyGILState_Ensure(); +#define SIP_UNBLOCK_THREADS PyGILState_Release(sipGIL);} +#else +typedef int sip_gilstate_t; +#define SIP_RELEASE_GIL(gs) +#define SIP_BLOCK_THREADS +#define SIP_UNBLOCK_THREADS +#endif + + +/* + * The metatype for a wrapper type. + */ +typedef struct _sipWrapperType { + PyHeapTypeObject super; /* The super-metatype. */ + struct _sipTypeDef *type; /* The additional type information. */ +} sipWrapperType; + + +/* + * A C/C++ object wrapped as a Python object. + */ +typedef struct _sipWrapper { + PyObject_HEAD + union { + void *cppPtr; /* C/C++ object pointer. */ + void *(*afPtr)(); /* Access function. */ + } u; + int flags; /* Object flags. */ + PyObject *dict; /* The instance dictionary. */ + struct _sipPySig *pySigList; /* Python signal list (complex). */ + struct _sipWrapper *next; /* Next object at this address. */ +} sipWrapper; + + +/* + * Some convenient function pointers. + */ +typedef void *(*sipInitFunc)(sipWrapper *,PyObject *,int *); +typedef void (*sipDeallocFunc)(sipWrapper *); +typedef void *(*sipCastFunc)(void *,sipWrapperType *); +typedef sipWrapperType *(*sipSubClassConvertFunc)(void *); +typedef void *(*sipForceConvertToFunc)(PyObject *,int *); +typedef int (*sipConvertToFunc)(PyObject *,void **,int *); +typedef PyObject *(*sipConvertFromFunc)(void *); +typedef struct _sipProxy *(*sipProxyFunc)(void); +typedef int (*sipVirtHandlerFunc)(void *,PyObject *,...); +typedef int (*sipEmitFunc)(sipWrapper *,PyObject *); + + +/* + * The information describing an enum value instance to be added to a + * dictionary. + */ +typedef struct _sipEnumValueInstanceDef { + char *evi_name; /* The enum value name. */ + int evi_val; /* The enum value value. */ +} sipEnumValueInstanceDef; + + +/* + * The information describing static instances. + */ +typedef struct _sipInstancesDef { + struct _sipClassInstanceDef *id_class; /* The classes. */ + struct _sipVoidPtrInstanceDef *id_voidp; /* The void *. */ + struct _sipCharInstanceDef *id_char; /* The chars. */ + struct _sipStringInstanceDef *id_string; /* The strings. */ + struct _sipLongInstanceDef *id_long; /* The longs. */ + struct _sipDoubleInstanceDef *id_double; /* The doubles. */ +} sipInstancesDef; + + +/* + * The information describing a super-class. + */ +typedef struct _sipSuperClassDef { + unsigned sc_class:16; /* The class number. */ + unsigned sc_module:8; /* The module number (255 for this one). */ + unsigned sc_last:1; /* The last in the list. */ +} sipSuperClassDef; + + +/* + * The information describing a sub-class convertor. + */ +typedef struct _sipSubClassConvertorDef { + sipSubClassConvertFunc scc_convertor; /* The convertor. */ + sipSuperClassDef scc_base; /* The encoded base type. */ + sipWrapperType *scc_basetype; /* The base type. */ +} sipSubClassConvertorDef; + + +/* + * The different Python slot types. + */ +typedef enum { + str_slot, /* __str__ */ + int_slot, /* __int__ */ + len_slot, /* __len__ */ + contains_slot, /* __contains__ */ + add_slot, /* __add__ for number */ + concat_slot, /* __add__ for sequence types */ + sub_slot, /* __sub__ */ + mul_slot, /* __mul__ for number types */ + repeat_slot, /* __mul__ for sequence types */ + div_slot, /* __div__ */ + mod_slot, /* __mod__ */ + and_slot, /* __and__ */ + or_slot, /* __or__ */ + xor_slot, /* __xor__ */ + lshift_slot, /* __lshift__ */ + rshift_slot, /* __rshift__ */ + iadd_slot, /* __iadd__ for number types */ + iconcat_slot, /* __iadd__ for sequence types */ + isub_slot, /* __isub__ */ + imul_slot, /* __imul__ for number types */ + irepeat_slot, /* __imul__ for sequence types */ + idiv_slot, /* __idiv__ */ + imod_slot, /* __imod__ */ + iand_slot, /* __iand__ */ + ior_slot, /* __ior__ */ + ixor_slot, /* __ixor__ */ + ilshift_slot, /* __ilshift__ */ + irshift_slot, /* __irshift__ */ + invert_slot, /* __invert__ */ + call_slot, /* __call__ */ + getitem_slot, /* __getitem__ */ + setitem_slot, /* __setitem__ */ + delitem_slot, /* __delitem__ */ + lt_slot, /* __lt__ */ + le_slot, /* __le__ */ + eq_slot, /* __eq__ */ + ne_slot, /* __ne__ */ + gt_slot, /* __gt__ */ + ge_slot, /* __ge__ */ + cmp_slot, /* __cmp__ */ + nonzero_slot, /* __nonzero__ */ + neg_slot, /* __neg__ */ + repr_slot /* __repr__ */ +} sipPySlotType; + + +/* + * The information describing a Python slot function. + */ +typedef struct _sipPySlotDef { + void *psd_func; /* The function. */ + sipPySlotType psd_type; /* The type. */ +} sipPySlotDef; + + +/* + * The information describing a type. + */ +typedef struct _sipTypeDef { + struct _sipExportedModuleDef *td_module; /* The module. */ + char *td_name; /* The name of the type. */ + int td_scope; /* The nr. of the scoping type. */ + sipSuperClassDef *td_supers; /* The super-types. */ + sipPySlotDef *td_pyslots; /* The table of Python slots. */ + int td_nrmethods; /* The number of lazy methods. */ + PyMethodDef *td_methods; /* The table of lazy methods. */ + int td_nrenums; /* The number of lazy enums. */ + sipEnumValueInstanceDef *td_enums; /* The table of lazy enums. */ + PyMethodDef *td_variables; /* The variable table. */ + sipInitFunc td_init; /* The initialisation function. */ + sipDeallocFunc td_dealloc; /* The deallocation function. */ + sipCastFunc td_cast; /* The cast function, 0 if a C struct. */ + sipForceConvertToFunc td_fcto; /* The force convert to function, 0 if a C++ namespace. */ + sipConvertToFunc td_cto; /* The convert to function. */ + sipProxyFunc td_proxy; /* The create proxy function. */ + struct _sipQtSignal *td_emit; /* Emit table for Qt signals. */ + sipInstancesDef td_instances; /* The static instances. */ +} sipTypeDef; + + +/* + * The information describing a mapped class. + */ +typedef struct _sipMappedTypeDef { + sipForceConvertToFunc mt_fcto; /* The force convert to function. */ + sipConvertToFunc mt_cto; /* The convert to function. */ + sipConvertFromFunc mt_cfrom; /* The convert from function. */ +} sipMappedTypeDef; + + +/* + * The information describing an imported module. + */ +typedef struct _sipImportedModuleDef { + char *im_name; /* The module name. */ + int im_version; /* The required version. */ + struct _sipExportedModuleDef *im_module; /* The imported module. */ +} sipImportedModuleDef; + + +/* + * The main client module structure. + */ +typedef struct _sipExportedModuleDef { + struct _sipExportedModuleDef *em_next; /* The next in the list. */ + char *em_name; /* The module name. */ + int em_version; /* The module version. */ + sipImportedModuleDef *em_imports; /* The imported modules. */ + int em_qobject_class; /* The index of the QObject class. */ + struct _sipWrapperType **em_types; /* The table of types. */ + sipMappedTypeDef **em_mappedtypes; /* The table of mapped types. */ + sipVirtHandlerFunc *em_virthandlers; /* The table of virtual handlers. */ + sipSubClassConvertorDef *em_convertors; /* The sub-class convertors. */ + sipInstancesDef em_instances; /* The static instances. */ + struct _sipLicenseDef *em_license; /* The license. */ +} sipExportedModuleDef; + + +/* + * The information describing a license to be added to a dictionary. + */ +typedef struct _sipLicenseDef { + char *lc_type; /* The type of license. */ + char *lc_licensee; /* The licensee. */ + char *lc_timestamp; /* The timestamp. */ + char *lc_signature; /* The signature. */ +} sipLicenseDef; + + +/* + * The information describing a void pointer instance to be added to a + * dictionary. + */ +typedef struct _sipVoidPtrInstanceDef { + char *vi_name; /* The void pointer name. */ + void *vi_val; /* The void pointer value. */ +} sipVoidPtrInstanceDef; + + +/* + * The information describing a char instance to be added to a dictionary. + */ +typedef struct _sipCharInstanceDef { + char *ci_name; /* The char name. */ + char ci_val; /* The char value. */ +} sipCharInstanceDef; + + +/* + * The information describing a string instance to be added to a dictionary. + */ +typedef struct _sipStringInstanceDef { + char *si_name; /* The string name. */ + char *si_val; /* The string value. */ +} sipStringInstanceDef; + + +/* + * The information describing a long instance to be added to a dictionary. + */ +typedef struct _sipLongInstanceDef { + char *li_name; /* The long name. */ + long li_val; /* The long value. */ +} sipLongInstanceDef; + + +/* + * The information describing a double instance to be added to a dictionary. + */ +typedef struct _sipDoubleInstanceDef { + char *di_name; /* The double name. */ + double di_val; /* The double value. */ +} sipDoubleInstanceDef; + + +/* + * The information describing a class instance to be added to a dictionary. + */ +typedef struct _sipClassInstanceDef { + char *ci_name; /* The class name. */ + void *ci_ptr; /* The actual instance. */ + struct _sipWrapperType **ci_type; /* A pointer to the Python type. */ + int ci_flags; /* The wrapping flags. */ +} sipClassInstanceDef; + + +/* + * Define a mapping between a wrapped type identified by a string and the + * corresponding Python type. + */ +typedef struct _sipStringTypeClassMap { + char *typeString; /* The type as a string. */ + struct _sipWrapperType **pyType; /* A pointer to the Python type. */ +} sipStringTypeClassMap; + + +/* + * Define a mapping between a wrapped type identified by an integer and the + * corresponding Python type. + */ +typedef struct _sipIntTypeClassMap { + int typeInt; /* The type as an integer. */ + struct _sipWrapperType **pyType; /* A pointer to the Python type. */ +} sipIntTypeClassMap; + + +/* + * A Python method's component parts. This allows us to re-create the method + * without changing the reference counts of the components. + */ +typedef struct _sipPyMethod { + PyObject *mfunc; /* The function. */ + PyObject *mself; /* Self if it is a bound method. */ + PyObject *mclass; /* The class. */ +} sipPyMethod; + + +/* + * Cache a reference to a Python member function. + */ +typedef struct _sipMethodCache { + int mcflags; /* Method cache flags. */ + sipPyMethod pyMethod; /* The method. */ +} sipMethodCache; + + +/* + * A slot (in the Qt, rather than Python, sense). + */ +typedef struct _sipSlot { + char *name; /* Name if a Qt or Python signal. */ + PyObject *pyobj; /* Signal or Qt slot object. */ + sipPyMethod meth; /* Python slot method, pyobj is NULL. */ + PyObject *weakSlot; /* A weak reference to the slot. */ +} sipSlot; + + +/* + * A proxy slot. + */ +typedef struct _sipProxy { + void *qproxy; /* The proxy QObject. */ + const char **slotTable; /* The table of slots. */ + sipSlot realSlot; /* The Python slot. */ + struct _sipWrapper *txSelf; /* The transmitter. */ + char *txSig; /* The transmitting signal. */ + const char *rxSlot; /* The receiving slot. */ + struct _sipProxy *next; /* Next in list. */ + struct _sipProxy *prev; /* Previous in list. */ +} sipProxy; + + +/* + * A receiver of a Python signal. + */ +typedef struct _sipPySigRx { + sipSlot rx; /* The receiver. */ + struct _sipPySigRx *next; /* Next in the list. */ +} sipPySigRx; + + +/* + * A Python signal. + */ +typedef struct _sipPySig { + char *name; /* The name of the signal. */ + sipPySigRx *rxlist; /* The list of receivers. */ + struct _sipPySig *next; /* Next in the list. */ +} sipPySig; + + +/* + * Maps the name of a Qt signal to a wrapper function to emit it. + */ +typedef struct _sipQtSignal { + char *st_name; /* The signal name. */ + sipEmitFunc st_emitfunc; /* The emitter function. */ +} sipQtSignal; + + +/* + * The API exported by the SIP module, ie. pointers to all the data and + * functions that can be used by generated code. + */ +typedef struct _sipAPIDef { + /* + * The following are part of the public API. + */ + void (*api_bad_catcher_result)(PyObject *method); + void (*api_bad_length_for_slice)(int seqlen,int slicelen); + PyObject *(*api_build_result)(int *isErr,char *fmt,...); + PyObject *(*api_call_method)(int *isErr,PyObject *method,char *fmt,...); + PyObject *(*api_class_name)(PyObject *self); + PyObject *(*api_connect_rx)(PyObject *txObj,const char *sig,PyObject *rxObj,const char *slot); + int (*api_convert_from_sequence_index)(int idx,int len); + void *(*api_convert_to_cpp)(PyObject *sipSelf,sipWrapperType *type,int *iserrp); + PyObject *(*api_disconnect_rx)(PyObject *txObj,const char *sig,PyObject *rxObj,const char *slot); + int (*api_emit_signal)(PyObject *self,const char *sig,PyObject *sigargs); + void (*api_free)(void *mem); + void *(*api_get_sender)(void); + PyObject *(*api_get_wrapper)(void *cppPtr,sipWrapperType *type); + void *(*api_malloc)(size_t nbytes); + sipWrapperType *(*api_map_int_to_class)(int typeInt,const sipIntTypeClassMap *map,int maplen); + sipWrapperType *(*api_map_string_to_class)(const char *typeString,const sipStringTypeClassMap *map,int maplen); + int (*api_parse_result)(int *isErr,PyObject *method,PyObject *res,char *fmt,...); + void (*api_trace)(unsigned mask,const char *fmt,...); + void (*api_transfer)(PyObject *self,int toCpp); + /* + * The following are not part of the public API. + */ + int (*api_export_module)(sipExportedModuleDef *client,unsigned api_major,unsigned api_minor,PyObject *mod_dict); + int (*api_add_enum_instances)(PyObject *dict,sipEnumValueInstanceDef *evi); + int (*api_parse_args)(int *argsParsedp,PyObject *sipArgs,char *fmt,...); + void (*api_common_ctor)(sipMethodCache *cache,int nrmeths); + void (*api_common_dtor)(sipWrapper *sipSelf); + PyObject *(*api_convert_from_void_ptr)(void *val); + void *(*api_convert_to_void_ptr)(PyObject *obj); + void (*api_no_ctor)(int argsParsed,char *classname); + void (*api_no_function)(int argsParsed,char *func); + void (*api_no_method)(int argsParsed,char *classname,char *method); + void (*api_bad_class)(const char *classname); + void (*api_bad_set_type)(const char *classname,const char *var); + void *(*api_get_cpp_ptr)(sipWrapper *w,sipWrapperType *type); + void *(*api_get_complex_cpp_ptr)(sipWrapper *w); + PyObject *(*api_is_py_method)(sip_gilstate_t *gil,sipMethodCache *pymc,sipWrapper *sipSelf,char *cname,char *mname); + PyObject *(*api_map_cpp_to_self)(void *cppPtr,sipWrapperType *type); + PyObject *(*api_map_cpp_to_self_sub_class)(void *cppPtr,sipWrapperType *type); + PyObject *(*api_new_cpp_to_self)(void *cppPtr,sipWrapperType *type,int initflags); + PyObject *(*api_new_cpp_to_self_sub_class)(void *cppPtr,sipWrapperType *type,int initflags); + void (*api_call_hook)(char *hookname); + void (*api_start_thread)(void); + void (*api_end_thread)(void); + void (*api_emit_to_slot)(void *sender,sipSlot *slot,char *fmt,...); + void (*api_raise_unknown_exception)(void); + void (*api_raise_class_exception)(sipWrapperType *type,void *ptr); + void (*api_raise_sub_class_exception)(sipWrapperType *type,void *ptr); + int (*api_add_class_instance)(PyObject *dict,char *name,void *cppPtr,sipWrapperType *wt); +} sipAPIDef; + + +/* + * Useful macros, not part of the public API. + */ +#define SIP_PY_OWNED 0x01 /* Owned by Python. */ +#define SIP_SIMPLE 0x02 /* If the instance is simple. */ +#define SIP_INDIRECT 0x04 /* If there is a level of indirection. */ +#define SIP_ACCFUNC 0x08 /* If there is an access function. */ +#define SIP_XTRA_REF 0x10 /* If C++ has an extra reference. */ +#define SIP_NOT_IN_MAP 0x20 /* If Python object not in the map. */ + +#define sipIsPyOwned(w) ((w) -> flags & SIP_PY_OWNED) +#define sipSetPyOwned(w) ((w) -> flags |= SIP_PY_OWNED) +#define sipResetPyOwned(w) ((w) -> flags &= ~SIP_PY_OWNED) +#define sipIsSimple(w) ((w) -> flags & SIP_SIMPLE) +#define sipIsIndirect(w) ((w) -> flags & SIP_INDIRECT) +#define sipIsAccessFunc(w) ((w) -> flags & SIP_ACCFUNC) +#define sipIsExtraRef(w) ((w) -> flags & SIP_XTRA_REF) +#define sipSetIsExtraRef(w) ((w) -> flags |= SIP_XTRA_REF) +#define sipResetIsExtraRef(w) ((w) -> flags &= ~SIP_XTRA_REF) +#define sipNotInMap(w) ((w) -> flags & SIP_NOT_IN_MAP) + + +#ifdef __cplusplus +} +#endif + + +#endif