📄 ambulantsupport.py
字号:
# This script generates a Python interface for an Apple Macintosh Manager.# It uses the "bgen" package to generate C code.# The function specifications are generated by scanning the mamager's header file,# using the "scantools" package (customized for this particular manager).import stringfrom bgen import *from bgenCxxSupport import *# Declarations that change for each managerMODNAME = 'ambulant' # The name of the module# The following is *usually* unchanged but may still require tuningMODPREFIX = 'PyAm' # The prefix for module-wide routinesINPUTFILE = 'ambulantgen.py' # The file generated by the scannerPY2CXXFILE = MODNAME + "module.cpp" # The Python to C++ glue codeCXX2PYFILE = MODNAME + "interface.cpp" # The C++ to Python glue codeCXX2PYDECLFILE = MODNAME + "interface.h" # The C++ to Python declarations# Create the type objectsincludestuff = """#define WITH_EXTERNAL_DOM 1#include "ambulant/config/config.h"#include "ambulant/version.h""""execfile("ambulantincludegen.py")includestuff = includestuff + """#include "ambulantinterface.h"#include "ambulantutilities.h"#include "ambulantmodule.h"extern PyObject *audio_format_choicesObj_New(ambulant::net::audio_format_choices *itself);extern int audio_format_choicesObj_Convert(PyObject *v, ambulant::net::audio_format_choices *p_itself);extern int cobject_Convert(PyObject *v, void **p_itself);/* Workaround for "const" added in Python 2.5. But removed before 2.5a1? */#if PY_VERSION_HEX >= 0x02050000 && PY_VERSION_HEX < 0x020500a1# define Py_KEYWORDS_STRING_TYPE const char#else# define Py_KEYWORDS_STRING_TYPE char#endif"""finalstuff = """// Helper routines to enable object identity to be maintained// across the bridge:cpppybridge *pycppbridge_getwrapper(PyObject *o){ if (!pycppbridge_Check(o)) { PyErr_Warn(PyExc_Warning, "ambulant: Passing non-pycppbridge object to C++"); return NULL; } pycppbridgeObject *bo = (pycppbridgeObject *)o; return bo->ob_wrapper;}voidpycppbridge_setwrapper(PyObject *o, cpppybridge *w){ if (!pycppbridge_Check(o)) { PyErr_SetString(PyExc_SystemError, "ambulant: attempt to set wrapper for non-bridged object"); } else { pycppbridgeObject *bo = (pycppbridgeObject *)o; if (bo->ob_wrapper) PyErr_SetString(PyExc_SystemError, "ambulant: attempt to set wrapper second time"); bo->ob_wrapper = w; }}// Declare initambulant as a C external:extern "C" void initambulant(); """initstuff = """PyEval_InitThreads();"""variablestuff=""""""print "=== Defining simple types ==="bool = OpaqueByValueType("bool", "bool")size_t = Type("size_t", "l")unsigned_int = Type("unsigned int", "l")progress_type = Type("ambulant::lib::transition_info::progress_type", "d")std_string = StdStringType()xml_string = StdStringType("ambulant::lib::xml_string")const_xml_string_ref = StdStringType("const ambulant::lib::xml_string&")q_name_pair = StdPairType(xml_string, xml_string, "ambulant::lib::q_name_pair")const_q_name_pair_ref = StdPairType(xml_string, xml_string, "const ambulant::lib::q_name_pair&", "ambulant::lib::q_name_pair")duration = StdPairType(bool, double, "ambulant::common::duration")InBuffer = VarInputBufferType('char', 'size_t', 'l')return_stringptr = Type("const char *", "z") # ONLY FOR RETURN VALUES!! May be None/NULL.# output_stringptr = Type("char *", "s") # BE CAREFUL!output_malloc_buf = MallocHeapOutputBufferType("char", "size_t", "l")# Ambulant-specificq_attributes_list = OpaqueByRefType("ambulant::lib::q_attributes_list", "ambulant_attributes_list")region_dim = OpaqueByRefType("ambulant::common::region_dim", "ambulant_region_dim")net_url = OpaqueByRefType("ambulant::net::url", "ambulant_url")rect = OpaqueByRefType("ambulant::lib::rect", "ambulant_rect")point = OpaqueByRefType("ambulant::lib::point", "ambulant_point")const_lib_point_ref = OpaqueByRefType("const ambulant::lib::point&", "ambulant_point")const_lib_rect_ref = OpaqueByRefType("const ambulant::lib::rect&", "ambulant_rect")size = OpaqueByRefType("ambulant::lib::size", "ambulant_size")zindex_t = Type("ambulant::common::zindex_t", "l")cookie_type = Type("ambulant::common::playable::cookie_type", "l")const_cookie_type = cookie_typecolor_t = Type("ambulant::lib::color_t", "l") # XXXX Split into RGBevent_priority = Type("ambulant::lib::event_priority", "l")timestamp_t = Type("ambulant::net::timestamp_t", "L")time_type = Type("ambulant::lib::timer::time_type", "l")tiling = Type("ambulant::common::tiling", "l")fit_t = Type("ambulant::common::fit_t", "l")sound_alignment = Type("ambulant::common::sound_alignment", "l")pause_display = Type("ambulant::common::pause_display", "l")pycobject = OpaqueByValueType("void*", "cobject")# This is a bit of a hack. These types are opaque, really.renderer_private_data_ptr = Type("ambulant::common::renderer_private_data *", "l")renderer_private_id = Type("ambulant::common::renderer_private_id", "l")# A helper object, used as baseclass for our Python objects to enable# bridging objects back-and-forth between Python and C++ while maintaining# object identity.class MyBridgeObjectDefinition(CxxMixin, PEP253Mixin, GlobalObjectDefinition): def __init__(self, name, prefix): GlobalObjectDefinition.__init__(self, name, prefix, None) self.constructors = [] def outputNew(self): pass def outputConvert(self): pass def outputCheck(self): pass def outputStructMembers(self): Output("cpppybridge *ob_wrapper;") def outputInitStructMembers(self): Output("ob_wrapper = NULL;") def outputCleanupStructMembers(self): Output("delete self->ob_wrapper;") Output("self->ob_wrapper = NULL;") def output_tp_new(self): Output("#define %s_tp_new PyType_GenericNew", self.prefix) # Our (opaque) objectsclass MyGlobalObjectDefinition(CxxMixin, PEP253Mixin, GlobalObjectDefinition): def __init__(self, name, prefix, itselftype): GlobalObjectDefinition.__init__(self, name, prefix, itselftype) self.constructors = [] def add(self, g, dupcheck=0): if g.name == self.name: g.setselftype(self.objecttype, self.itselftype) self.constructors.append(g) print "Adding constructor for", self.name else: GlobalObjectDefinition.add(self, g, dupcheck) def outputCheckNewArg(self): Output('if (itself == NULL)') OutLbrace() Output('Py_INCREF(Py_None);') Output('return Py_None;') OutRbrace() CxxMixin.outputCheckNewArg(self) # XXX Add refcount, if needed def outputCheckConvertArg(self): Output('if (v == Py_None)') OutLbrace() Output('*p_itself = NULL;') Output('return 1;') OutRbrace() CxxMixin.outputCheckConvertArg(self) def outputStructMembers(self): Output("void *ob_dummy_wrapper; // Overlays bridge object storage") GlobalObjectDefinition.outputStructMembers(self) # XXX Output("bool owned;") def outputInitStructMembers(self): Output("it->ob_dummy_wrapper = NULL; // XXXX Should be done in base class") GlobalObjectDefinition.outputInitStructMembers(self) # XXX init owned, if needed def outputCleanupStructMembers(self): # XXX For refcounted objects decref # XXX For owned objects delete pass def outputCompare(self): Output() Output("static int %s_compare(%s *self, %s *other)", self.prefix, self.objecttype, self.objecttype) OutLbrace() Output("if ( self->ob_itself > other->ob_itself ) return 1;") Output("if ( self->ob_itself < other->ob_itself ) return -1;") Output("return 0;") OutRbrace() def outputHash(self): Output() Output("static int %s_hash(%s *self)", self.prefix, self.objecttype) OutLbrace() Output("return (int)self->ob_itself;") OutRbrace() def output_tp_newBody(self): Output("PyObject *_self;") Output() Output("if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;") Output("((%s *)_self)->ob_itself = NULL;", self.objecttype) ##Output("((%s *)self)->ob_freeit = CFRelease;", self.objecttype) Output("return _self;") def output_tp_initBody(self): Output("%s itself;", self.itselftype) Output("Py_KEYWORDS_STRING_TYPE *kw[] = {\"itself\", 0};") Output() for con in self.constructors: con.outputConstructorBody() Output("if (PyArg_ParseTupleAndKeywords(_args, _kwds, \"O&\", kw, %s_Convert, &itself))", self.prefix) OutLbrace() Output("((%s *)_self)->ob_itself = itself;", self.objecttype) Output("return 0;") OutRbrace() Output("return -1;") # Create the generator groups and link themmodule = CxxModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff, variablestuff)functions = []# Start with adding the bridging base classpycppbridge = MyBridgeObjectDefinition("pycppbridge", "pycppbridge")module.addobject(pycppbridge)print "=== generating object definitions ==="execfile("ambulantobjgen.py")print "=== declaring more types ==="# XXXX Temporarily disabledmethods_none_playable_factory = []audio_format = TupleType("ambulant::net::audio_format", (std_string, "mime_type"), (std_string, "name"), (FakeType("(void *)0"), "parameters"), (int, "samplerate"), (int, "channels"), (int, "bits"))audio_format_ref = TupleType("ambulant::net::audio_format&", (std_string, "mime_type"), (std_string, "name"), (FakeType("(void *)0"), "parameters"), (int, "samplerate"), (int, "channels"), (int, "bits"))video_format = TupleType("ambulant::net::video_format", (std_string, "mime_type"), (std_string, "name"), (FakeType("(void*)0"), "parameters"), (timestamp_t, "frameduration"), (int, "width"), (int, "height"))video_format_ref = TupleType("ambulant::net::video_format&", (std_string, "mime_type"), (std_string, "name"), (FakeType("(void*)0"), "parameters"), (timestamp_t, "frameduration"), (int, "width"), (int, "height"))const_audio_format_ref = TupleType("const ambulant::net::audio_format&", (std_string, "mime_type"), (std_string, "name"), (FakeType("(void *)0"), "parameters"), (int, "samplerate"), (int, "channels"), (int, "bits")) class audio_format_choicesObjectDefinition(MyGlobalObjectDefinition): baseclass = None argref = "*" argconst = "const " def output_tp_newBody(self): Output("PyObject *_self;") Output() Output("if ((_self = type->tp_alloc(type, 0)) == NULL) return NULL;") #Output("((%s *)_self)->ob_itself = NULL;", self.objecttype) Output("return _self;")
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -