Last-minute fix for Jim H: don't die after del sys.stdout
[python/dscho.git] / Mac / Modules / snd / sndsupport.py
blobb3b32f1999b1a5f6b0e77acfafa9bd3bdef105a6
1 # This script generates the Sound interface for Python.
2 # It uses the "bgen" package to generate C code.
3 # It execs the file sndgen.py which contain the function definitions
4 # (sndgen.py was generated by sndscan.py, scanning the <Sound.h> header file).
6 import addpack
7 addpack.addpack(':Tools:bgen:bgen')
9 from macsupport import *
12 # define our own function and module generators
14 class SndMixIn: pass
16 class SndFunction(SndMixIn, OSErrFunctionGenerator): pass
17 class SndMethod(SndMixIn, OSErrMethodGenerator): pass
20 # includestuff etc. are imported from macsupport
22 includestuff = includestuff + """
23 #include <Sound.h>
25 #ifndef HAVE_UNIVERSAL_HEADERS
26 #define SndCallBackUPP ProcPtr
27 #define NewSndCallBackProc(x) ((SndCallBackProcPtr)(x))
28 #define SndListHandle Handle
29 #endif
30 """
32 initstuff = initstuff + """
33 """
36 # define types used for arguments (in addition to standard and macsupport types)
38 class SndChannelPtrType(OpaqueByValueType):
39 def declare(self, name):
40 # Initializing all SndChannelPtr objects to 0 saves
41 # special-casing NewSndChannel(), where it is formally an
42 # input-output parameter but we treat it as output-only
43 # (since Python users are not supposed to allocate memory)
44 Output("SndChannelPtr %s = 0;", name)
46 SndChannelPtr = SndChannelPtrType('SndChannelPtr', 'SndCh')
48 SndCommand = OpaqueType('SndCommand', 'SndCmd')
49 SndCommand_ptr = OpaqueType('SndCommand', 'SndCmd')
50 SndListHandle = OpaqueByValueType("SndListHandle", "ResObj")
52 class SndCallBackType(InputOnlyType):
53 def __init__(self):
54 Type.__init__(self, 'PyObject*', 'O')
55 def getargsCheck(self, name):
56 Output("if (%s != Py_None && !PyCallable_Check(%s))", name, name)
57 OutLbrace()
58 Output('PyErr_SetString(PyExc_TypeError, "callback must be callable");')
59 Output("goto %s__error__;", name)
60 OutRbrace()
61 def passInput(self, name):
62 return "NewSndCallBackProc(SndCh_UserRoutine)"
63 def cleanup(self, name):
64 # XXX This knows it is executing inside the SndNewChannel wrapper
65 Output("if (_res != NULL && %s != Py_None)", name)
66 OutLbrace()
67 Output("SndChannelObject *p = (SndChannelObject *)_res;")
68 Output("p->ob_itself->userInfo = (long)p;")
69 Output("Py_INCREF(%s);", name)
70 Output("p->ob_callback = %s;", name)
71 OutRbrace()
72 DedentLevel()
73 Output(" %s__error__: ;", name)
74 IndentLevel()
76 SndCallBackProcPtr = SndCallBackType()
77 SndCallBackUPP = SndCallBackProcPtr
79 SndCompletionProcPtr = FakeType('(SndCompletionProcPtr)0') # XXX
80 SndCompletionUPP = SndCompletionProcPtr
82 ##InOutBuf128 = FixedInputOutputBufferType(128)
83 StateBlock = StructInputOutputBufferType('StateBlock')
85 AudioSelectionPtr = FakeType('0') # XXX
87 ProcPtr = FakeType('0') # XXX
88 FilePlayCompletionUPP = FakeType('0') # XXX
90 SCStatus = StructOutputBufferType('SCStatus')
91 SMStatus = StructOutputBufferType('SMStatus')
92 CompressionInfo = StructOutputBufferType('CompressionInfo')
94 includestuff = includestuff + """
95 #include <OSUtils.h> /* for Set(Current)A5 */
97 /* Create a SndCommand object (an (int, int, int) tuple) */
98 static PyObject *
99 SndCmd_New(SndCommand *pc)
101 return Py_BuildValue("hhl", pc->cmd, pc->param1, pc->param2);
104 /* Convert a SndCommand argument */
105 static int
106 SndCmd_Convert(PyObject *v, SndCommand *pc)
108 int len;
109 pc->param1 = 0;
110 pc->param2 = 0;
111 if (PyTuple_Check(v)) {
112 if (PyArg_ParseTuple(v, "h|hl", &pc->cmd, &pc->param1, &pc->param2))
113 return 1;
114 PyErr_Clear();
115 return PyArg_ParseTuple(v, "hhs#", &pc->cmd, &pc->param1, &pc->param2, &len);
117 return PyArg_Parse(v, "h", &pc->cmd);
120 static pascal void SndCh_UserRoutine(SndChannelPtr chan, SndCommand *cmd); /* Forward */
124 finalstuff = finalstuff + """
125 /* Routine passed to Py_AddPendingCall -- call the Python callback */
126 static int
127 SndCh_CallCallBack(arg)
128 void *arg;
130 SndChannelObject *p = (SndChannelObject *)arg;
131 PyObject *args;
132 PyObject *res;
133 args = Py_BuildValue("(O(hhl))",
134 p, p->ob_cmd.cmd, p->ob_cmd.param1, p->ob_cmd.param2);
135 res = PyEval_CallObject(p->ob_callback, args);
136 Py_DECREF(args);
137 if (res == NULL)
138 return -1;
139 Py_DECREF(res);
140 return 0;
143 /* Routine passed to NewSndChannel -- schedule a call to SndCh_CallCallBack */
144 static pascal void
145 SndCh_UserRoutine(SndChannelPtr chan, SndCommand *cmd)
147 SndChannelObject *p = (SndChannelObject *)(chan->userInfo);
148 if (p->ob_callback != NULL) {
149 long A5 = SetA5(p->ob_A5);
150 p->ob_cmd = *cmd;
151 Py_AddPendingCall(SndCh_CallCallBack, (void *)p);
152 SetA5(A5);
158 # create the module and object definition and link them
160 class SndObjectDefinition(ObjectDefinition):
162 def outputStructMembers(self):
163 ObjectDefinition.outputStructMembers(self)
164 Output("/* Members used to implement callbacks: */")
165 Output("PyObject *ob_callback;")
166 Output("long ob_A5;");
167 Output("SndCommand ob_cmd;")
169 def outputInitStructMembers(self):
170 ObjectDefinition.outputInitStructMembers(self)
171 Output("it->ob_callback = NULL;")
172 Output("it->ob_A5 = SetCurrentA5();");
174 def outputCleanupStructMembers(self):
175 ObjectDefinition.outputCleanupStructMembers(self)
176 Output("Py_XDECREF(self->ob_callback);")
178 def outputFreeIt(self, itselfname):
179 Output("SndDisposeChannel(%s, 1);", itselfname)
182 sndobject = SndObjectDefinition('SndChannel', 'SndCh', 'SndChannelPtr')
183 module = MacModule('Snd', 'Snd', includestuff, finalstuff, initstuff)
184 module.addobject(sndobject)
187 # create lists of functions and object methods
189 functions = []
190 sndmethods = []
193 # populate the lists
195 execfile('sndgen.py')
198 # add the functions and methods to the module and object, respectively
200 for f in functions: module.add(f)
201 for f in sndmethods: sndobject.add(f)
204 # generate output
206 SetOutputFileName('Sndmodule.c')
207 module.generate()