History

lib/gen_external.py: rewrote wrapper

Paul Brossier committed 10 years ago

Commit ccb9fb51 parent fbd7c804 files · +669 −764Browse files

Showing the changes to python (4 of 4 files). Show all

Unified · Split

4 files
  1. python/lib/gen_code.py +487 −0
  2. python/lib/gen_external.py +182 −0
  3. python/lib/gen_pyobject.py +0 −531
  4. python/lib/generator.py +0 −233
python/lib/gen_code.py+487−0
@@ -0,0 +1,487 @@
1+aubiodefvalue = {
2+ # we have some clean up to do
3+ 'buf_size': 'Py_default_vector_length',
4+ 'win_s': 'Py_default_vector_length',
5+ # and here too
6+ 'hop_size': 'Py_default_vector_length / 2',
7+ 'hop_s': 'Py_default_vector_length / 2',
8+ # these should be alright
9+ 'samplerate': 'Py_aubio_default_samplerate',
10+ # now for the non obvious ones
11+ 'n_filters': '40',
12+ 'n_coeffs': '13',
13+ 'nelems': '10',
14+ 'flow': '0.',
15+ 'fhig': '1.',
16+ 'ilow': '0.',
17+ 'ihig': '1.',
18+ 'thrs': '0.5',
19+ 'ratio': '0.5',
20+ 'method': '"default"',
21+ 'uri': '"none"',
22+ }
23+
24+member_types = {
25+ 'name': 'type',
26+ 'char_t*': 'T_STRING',
27+ 'uint_t': 'T_INT',
28+ 'smpl_t': 'T_FLOAT',
29+ }
30+
31+pyfromtype_fn = {
32+ 'smpl_t': 'PyFloat_FromDouble',
33+ 'uint_t': 'PyLong_FromLong', # was: 'PyInt_FromLong',
34+ 'fvec_t*': 'PyAubio_CFvecToArray',
35+ 'fmat_t*': 'PyAubio_CFmatToArray',
36+ }
37+
38+pytoaubio_fn = {
39+ 'fvec_t*': 'PyAubio_ArrayToCFvec',
40+ 'cvec_t*': 'PyAubio_ArrayToCCvec',
41+ 'fmat_t*': 'PyAubio_ArrayToCFmat',
42+ }
43+
44+pyfromaubio_fn = {
45+ 'fvec_t*': 'PyAubio_CFvecToArray',
46+ 'cvec_t*': 'PyAubio_CCvecToArray',
47+ 'fmat_t*': 'PyAubio_CFmatToArray',
48+ }
49+
50+newfromtype_fn = {
51+ 'fvec_t*': 'new_fvec',
52+ 'fmat_t*': 'new_fmat',
53+ 'cvec_t*': 'new_cvec',
54+ }
55+
56+delfromtype_fn = {
57+ 'fvec_t*': 'del_fvec',
58+ 'fmat_t*': 'del_fmat',
59+ 'cvec_t*': 'del_cvec',
60+ }
61+
62+param_init = {
63+ 'char_t*': 'NULL',
64+ 'uint_t': '0',
65+ 'sint_t': 0,
66+ 'smpl_t': 0.,
67+ 'lsmp_t': 0.,
68+ }
69+
70+pyargparse_chars = {
71+ 'smpl_t': 'f',
72+ 'uint_t': 'I',
73+ 'sint_t': 'I',
74+ 'char_t*': 's',
75+ 'fmat_t*': 'O',
76+ 'fvec_t*': 'O',
77+ }
78+
79+objoutsize = {
80+ 'onset': '1',
81+ 'pitch': '1',
82+ 'wavetable': 'self->hop_size',
83+ 'sampler': 'self->hop_size',
84+ 'mfcc': 'self->n_coeffs',
85+ 'specdesc': '1',
86+ 'tempo': '1',
87+ 'filterbank': 'self->n_filters',
88+ }
89+
90+def get_name(proto):
91+ name = proto.replace(' *', '* ').split()[1].split('(')[0]
92+ name = name.replace('*','')
93+ if name == '': raise ValueError(proto + "gave empty name")
94+ return name
95+
96+def get_return_type(proto):
97+ import re
98+ paramregex = re.compile('(\w+ ?\*?).*')
99+ outputs = paramregex.findall(proto)
100+ assert len(outputs) == 1
101+ return outputs[0].replace(' ', '')
102+
103+def split_type(arg):
104+ """ arg = 'foo *name'
105+ return ['foo*', 'name'] """
106+ l = arg.split()
107+ type_arg = {'type': l[0], 'name': l[1]}
108+ # ['foo', '*name'] -> ['foo*', 'name']
109+ if l[-1].startswith('*'):
110+ #return [l[0]+'*', l[1][1:]]
111+ type_arg['type'] = l[0] + '*'
112+ type_arg['name'] = l[1][1:]
113+ # ['foo', '*', 'name'] -> ['foo*', 'name']
114+ if len(l) == 3:
115+ #return [l[0]+l[1], l[2]]
116+ type_arg['type'] = l[0]+l[1]
117+ type_arg['name'] = l[2]
118+ else:
119+ #return l
120+ pass
121+ return type_arg
122+
123+def get_params(proto):
124+ """ get the list of parameters from a function prototype
125+ example: proto = "int main (int argc, char ** argv)"
126+ returns: ['int argc', 'char ** argv']
127+ """
128+ import re
129+ paramregex = re.compile('[\(, ](\w+ \*?\*? ?\w+)[, \)]')
130+ return paramregex.findall(proto)
131+
132+def get_params_types_names(proto):
133+ """ get the list of parameters from a function prototype
134+ example: proto = "int main (int argc, char ** argv)"
135+ returns: [['int', 'argc'], ['char **','argv']]
136+ """
137+ return list(map(split_type, get_params(proto)))
138+
139+
140+class MappedObject(object):
141+
142+ def __init__(self, prototypes):
143+ self.prototypes = prototypes
144+
145+ self.shortname = prototypes['shortname']
146+ self.longname = prototypes['longname']
147+ self.new_proto = prototypes['new'][0]
148+ self.del_proto = prototypes['del'][0]
149+ self.do_proto = prototypes['do'][0]
150+ self.input_params = get_params_types_names(self.new_proto)
151+ self.input_params_list = "; ".join(get_params(self.new_proto))
152+ self.outputs = get_params_types_names(self.do_proto)[2:]
153+ self.outputs_flat = get_params(self.do_proto)[2:]
154+ self.output_results = ", ".join(self.outputs_flat)
155+
156+ def gen_code(self):
157+ out = ""
158+ out += self.gen_struct()
159+ out += self.gen_doc()
160+ out += self.gen_new()
161+ out += self.gen_init()
162+ out += self.gen_del()
163+ out += self.gen_do()
164+ out += self.gen_memberdef()
165+ out += self.gen_set()
166+ out += self.gen_get()
167+ out += self.gen_methodef()
168+ out += self.gen_typeobject()
169+ return out
170+
171+ def gen_struct(self):
172+ out = """
173+// {shortname} structure
174+typedef struct{{
175+ PyObject_HEAD
176+ // pointer to aubio object
177+ {longname} *o;
178+ // input parameters
179+ {input_params_list};
180+ // output results
181+ {output_results};
182+}} Py_{shortname};
183+"""
184+ return out.format(**self.__dict__)
185+
186+ def gen_doc(self):
187+ out = """
188+// TODO: add documentation
189+static char Py_{shortname}_doc[] = \"undefined\";
190+ """
191+ return out.format(**self.__dict__)
192+
193+ def gen_new(self):
194+ out = """
195+// new {shortname}
196+static PyObject *
197+Py_{shortname}_new (PyTypeObject * pytype, PyObject * args, PyObject * kwds)
198+{{
199+ Py_{shortname} *self;
200+""".format(**self.__dict__)
201+ params = self.input_params
202+ for p in params:
203+ out += """
204+ {type} {name} = {defval};""".format(defval = param_init[p['type']], **p)
205+ plist = ", ".join(["\"%s\"" % p['name'] for p in params])
206+ out += """
207+ static char *kwlist[] = {{ {plist}, NULL }};""".format(plist = plist)
208+ argchars = "".join([pyargparse_chars[p['type']] for p in params])
209+ arglist = ", ".join(["&%s" % p['name'] for p in params])
210+ out += """
211+ if (!PyArg_ParseTupleAndKeywords (args, kwds, "|{argchars}", kwlist,
212+ {arglist})) {{
213+ return NULL;
214+ }}
215+""".format(argchars = argchars, arglist = arglist)
216+ out += """
217+ self = (Py_{shortname} *) pytype->tp_alloc (pytype, 0);
218+ if (self == NULL) {{
219+ return NULL;
220+ }}
221+""".format(**self.__dict__)
222+ params = self.input_params
223+ for p in params:
224+ out += self.check_valid(p)
225+ out += """
226+ return (PyObject *)self;
227+}
228+"""
229+ return out
230+
231+ def check_valid(self, p):
232+ if p['type'] == 'uint_t':
233+ return self.check_valid_uint(p)
234+ if p['type'] == 'char_t*':
235+ return self.check_valid_char(p)
236+ else:
237+ print ("ERROR, no idea how to check %s for validity" % p['type'])
238+
239+ def check_valid_uint(self, p):
240+ name = p['name']
241+ return """
242+ self->{name} = {defval};
243+ if ((sint_t){name} > 0) {{
244+ self->{name} = {name};
245+ }} else if ((sint_t){name} < 0) {{
246+ PyErr_SetString (PyExc_ValueError, "can not use negative value for {name}");
247+ return NULL;
248+ }}
249+""".format(defval = aubiodefvalue[name], name = name)
250+
251+ def check_valid_char(self, p):
252+ name = p['name']
253+ return """
254+ self->{name} = {defval};
255+ if ({name} != NULL) {{
256+ self->{name} = {name};
257+ }}
258+""".format(defval = aubiodefvalue[name], name = name)
259+
260+ def gen_init(self):
261+ out = """
262+// init {shortname}
263+static int
264+Py_{shortname}_init (Py_{shortname} * self, PyObject * args, PyObject * kwds)
265+{{
266+""".format(**self.__dict__)
267+ new_name = get_name(self.new_proto)
268+ new_params = ", ".join(["self->%s" % s['name'] for s in self.input_params])
269+ out += """
270+ self->o = {new_name}({new_params});
271+""".format(new_name = new_name, new_params = new_params)
272+ paramchars = "%s"
273+ paramvals = "self->method"
274+ out += """
275+ // return -1 and set error string on failure
276+ if (self->o == NULL) {{
277+ //char_t errstr[30 + strlen(self->uri)];
278+ //sprintf(errstr, "error creating {shortname} with params {paramchars}", {paramvals});
279+ char_t errstr[60];
280+ sprintf(errstr, "error creating {shortname} with given params");
281+ PyErr_SetString (PyExc_Exception, errstr);
282+ return -1;
283+ }}
284+""".format(paramchars = paramchars, paramvals = paramvals, **self.__dict__)
285+ output_create = ""
286+ for o in self.outputs:
287+ output_create += """
288+ self->{name} = {create_fn}({output_size});""".format(name = o['name'], create_fn = newfromtype_fn[o['type']], output_size = objoutsize[self.shortname])
289+ out += """
290+ // TODO get internal params after actual object creation?
291+"""
292+ out += """
293+ // create outputs{output_create}
294+""".format(output_create = output_create)
295+ out += """
296+ return 0;
297+}
298+"""
299+ return out
300+
301+ def gen_memberdef(self):
302+ out = """
303+static PyMemberDef Py_{shortname}_members[] = {{
304+""".format(**self.__dict__)
305+ for p in get_params_types_names(self.new_proto):
306+ tmp = " {{\"{name}\", {ttype}, offsetof (Py_{shortname}, {name}), READONLY, \"TODO documentation\"}},\n"
307+ pytype = member_types[p['type']]
308+ out += tmp.format(name = p['name'], ttype = pytype, shortname = self.shortname)
309+ out += """ {NULL}, // sentinel
310+};
311+"""
312+ return out
313+
314+ def gen_del(self):
315+ out = """
316+// del {shortname}
317+static void
318+Py_{shortname}_del (Py_{shortname} * self, PyObject * unused)
319+{{""".format(**self.__dict__)
320+ for o in self.outputs:
321+ name = o['name']
322+ del_out = delfromtype_fn[o['type']]
323+ out += """
324+ {del_out}(self->{name});""".format(del_out = del_out, name = name)
325+ del_fn = get_name(self.del_proto)
326+ out += """
327+ {del_fn}(self->o);
328+ Py_TYPE(self)->tp_free((PyObject *) self);
329+}}
330+""".format(del_fn = del_fn)
331+ return out
332+
333+ def gen_do(self):
334+ do_fn = get_name(self.do_proto)
335+ input_param = get_params_types_names(self.do_proto)[1];
336+ pytoaubio = pytoaubio_fn[input_param['type']]
337+ output = self.outputs[0]
338+ out = """
339+// do {shortname}
340+static PyObject*
341+Py_{shortname}_do (Py_{shortname} * self, PyObject * args)
342+{{
343+ PyObject * in_obj;
344+ {input_type} {input_name};
345+
346+ if (!PyArg_ParseTuple (args, "O", &in_obj)) {{
347+ return NULL;
348+ }}
349+ {input_name} = {pytoaubio} (in_obj);
350+ if ({input_name} == NULL) {{
351+ return NULL;
352+ }}
353+
354+ {do_fn}(self->o, {input_name}, {outputs});
355+
356+ return (PyObject *) {aubiotonumpy} ({outputs});
357+}}
358+"""
359+ return out.format(do_fn = do_fn,
360+ shortname = self.prototypes['shortname'],
361+ input_name = input_param['name'],
362+ input_type= input_param['type'],
363+ pytoaubio = pytoaubio,
364+ outputs = ", ".join(["self->%s" % p['name'] for p in self.outputs]),
365+ aubiotonumpy = pyfromaubio_fn[output['type']],
366+ )
367+
368+ def gen_set(self):
369+ out = """
370+// {shortname} setters
371+""".format(**self.__dict__)
372+ for set_param in self.prototypes['set']:
373+ params = get_params_types_names(set_param)[1]
374+ paramtype = params['type']
375+ method_name = get_name(set_param)
376+ param = method_name.split('aubio_'+self.shortname+'_set_')[-1]
377+ pyparamtype = pyargparse_chars[paramtype]
378+ out += """
379+static PyObject *
380+Pyaubio_{shortname}_set_{param} (Py_{shortname} *self, PyObject *args)
381+{{
382+ uint_t err = 0;
383+ {paramtype} {param};
384+
385+ if (!PyArg_ParseTuple (args, "{pyparamtype}", &{param})) {{
386+ return NULL;
387+ }}
388+ err = aubio_{shortname}_set_{param} (self->o, {param});
389+
390+ if (err > 0) {{
391+ PyErr_SetString (PyExc_ValueError, "error running aubio_{shortname}_set_{param}");
392+ return NULL;
393+ }}
394+ Py_RETURN_NONE;
395+}}
396+""".format(param = param, paramtype = paramtype, pyparamtype = pyparamtype, **self.__dict__)
397+ return out
398+
399+ def gen_get(self):
400+ out = """
401+// {shortname} getters
402+""".format(**self.__dict__)
403+ for method in self.prototypes['get']:
404+ params = get_params_types_names(method)
405+ method_name = get_name(method)
406+ assert len(params) == 1, \
407+ "get method has more than one parameter %s" % params
408+ param = method_name.split('aubio_'+self.shortname+'_get_')[-1]
409+ paramtype = get_return_type(method)
410+ ptypeconv = pyfromtype_fn[paramtype]
411+ out += """
412+static PyObject *
413+Pyaubio_{shortname}_get_{param} (Py_{shortname} *self, PyObject *unused)
414+{{
415+ {ptype} {param} = aubio_{shortname}_get_{param} (self->o);
416+ return (PyObject *){ptypeconv} ({param});
417+}}
418+""".format(param = param, ptype = paramtype, ptypeconv = ptypeconv,
419+ **self.__dict__)
420+ return out
421+
422+ def gen_methodef(self):
423+ out = """
424+static PyMethodDef Py_{shortname}_methods[] = {{""".format(**self.__dict__)
425+ for m in self.prototypes['set']:
426+ name = get_name(m)
427+ shortname = name.replace('aubio_%s_' % self.shortname, '')
428+ out += """
429+ {{"{shortname}", (PyCFunction) Py{name},
430+ METH_VARARGS, ""}},""".format(name = name, shortname = shortname)
431+ for m in self.prototypes['get']:
432+ name = get_name(m)
433+ shortname = name.replace('aubio_%s_' % self.shortname, '')
434+ out += """
435+ {{"{shortname}", (PyCFunction) Py{name},
436+ METH_NOARGS, ""}},""".format(name = name, shortname = shortname)
437+ out += """
438+ {NULL} /* sentinel */
439+};
440+"""
441+ return out
442+
443+ def gen_typeobject(self):
444+ return """
445+PyTypeObject Py_{shortname}Type = {{
446+ //PyObject_HEAD_INIT (NULL)
447+ //0,
448+ PyVarObject_HEAD_INIT (NULL, 0)
449+ "aubio.{shortname}",
450+ sizeof (Py_{shortname}),
451+ 0,
452+ (destructor) Py_{shortname}_del,
453+ 0,
454+ 0,
455+ 0,
456+ 0,
457+ 0,
458+ 0,
459+ 0,
460+ 0,
461+ 0,
462+ (ternaryfunc)Py_{shortname}_do,
463+ 0,
464+ 0,
465+ 0,
466+ 0,
467+ Py_TPFLAGS_DEFAULT,
468+ Py_{shortname}_doc,
469+ 0,
470+ 0,
471+ 0,
472+ 0,
473+ 0,
474+ 0,
475+ Py_{shortname}_methods,
476+ Py_{shortname}_members,
477+ 0,
478+ 0,
479+ 0,
480+ 0,
481+ 0,
482+ 0,
483+ (initproc) Py_{shortname}_init,
484+ 0,
485+ Py_{shortname}_new,
486+}};
487+""".format(**self.__dict__)
python/lib/gen_external.py+182−0
@@ -0,0 +1,182 @@
1+import os
2+
3+header = """// this file is generated! do not modify
4+#include "aubio-types.h"
5+"""
6+
7+skip_objects = [
8+ # already in ext/
9+ 'fft',
10+ 'pvoc',
11+ 'filter',
12+ 'filterbank',
13+ #'resampler',
14+ # AUBIO_UNSTABLE
15+ 'hist',
16+ 'parameter',
17+ 'scale',
18+ 'beattracking',
19+ 'resampler',
20+ 'peakpicker',
21+ 'pitchfcomb',
22+ 'pitchmcomb',
23+ 'pitchschmitt',
24+ 'pitchspecacf',
25+ 'pitchyin',
26+ 'pitchyinfft',
27+ 'sink',
28+ 'sink_apple_audio',
29+ 'sink_sndfile',
30+ 'sink_wavwrite',
31+ #'mfcc',
32+ 'source',
33+ 'source_apple_audio',
34+ 'source_sndfile',
35+ 'source_avcodec',
36+ 'source_wavread',
37+ #'sampler',
38+ 'audio_unit',
39+
40+ 'tss',
41+ ]
42+
43+
44+def get_cpp_objects():
45+
46+ cpp_output = [l.strip() for l in os.popen('cpp -DAUBIO_UNSTABLE=1 -I../build/src ../src/aubio.h').readlines()]
47+ #cpp_output = [l.strip() for l in os.popen('cpp -DAUBIO_UNSTABLE=0 -I../build/src ../src/onset/onset.h').readlines()]
48+ #cpp_output = [l.strip() for l in os.popen('cpp -DAUBIO_UNSTABLE=0 -I../build/src ../src/pitch/pitch.h').readlines()]
49+
50+ cpp_output = filter(lambda y: len(y) > 1, cpp_output)
51+ cpp_output = filter(lambda y: not y.startswith('#'), cpp_output)
52+ cpp_output = list(cpp_output)
53+
54+ i = 1
55+ while 1:
56+ if i >= len(cpp_output): break
57+ if cpp_output[i-1].endswith(',') or cpp_output[i-1].endswith('{') or cpp_output[i].startswith('}'):
58+ cpp_output[i] = cpp_output[i-1] + ' ' + cpp_output[i]
59+ cpp_output.pop(i-1)
60+ else:
61+ i += 1
62+
63+ typedefs = filter(lambda y: y.startswith ('typedef struct _aubio'), cpp_output)
64+
65+ cpp_objects = [a.split()[3][:-1] for a in typedefs]
66+
67+ return cpp_output, cpp_objects
68+
69+def generate_external(output_path):
70+ os.mkdir(output_path)
71+ sources_list = []
72+ cpp_output, cpp_objects = get_cpp_objects()
73+ lib = {}
74+
75+ for o in cpp_objects:
76+ if o[:6] != 'aubio_':
77+ continue
78+ shortname = o[6:-2]
79+ if shortname in skip_objects:
80+ continue
81+ lib[shortname] = {'struct': [], 'new': [], 'del': [], 'do': [], 'get': [], 'set': [], 'other': []}
82+ lib[shortname]['longname'] = o
83+ lib[shortname]['shortname'] = shortname
84+ for fn in cpp_output:
85+ if o[:-1] in fn:
86+ #print "found", o[:-1], "in", fn
87+ if 'typedef struct ' in fn:
88+ lib[shortname]['struct'].append(fn)
89+ elif '_do' in fn:
90+ lib[shortname]['do'].append(fn)
91+ elif 'new_' in fn:
92+ lib[shortname]['new'].append(fn)
93+ elif 'del_' in fn:
94+ lib[shortname]['del'].append(fn)
95+ elif '_get_' in fn:
96+ lib[shortname]['get'].append(fn)
97+ elif '_set_' in fn:
98+ lib[shortname]['set'].append(fn)
99+ else:
100+ #print "no idea what to do about", fn
101+ lib[shortname]['other'].append(fn)
102+
103+ """
104+ for fn in cpp_output:
105+ found = 0
106+ for o in lib:
107+ for family in lib[o]:
108+ if fn in lib[o][family]:
109+ found = 1
110+ if found == 0:
111+ print "missing", fn
112+
113+ for o in lib:
114+ for family in lib[o]:
115+ if type(lib[o][family]) == str:
116+ print ( "{:15s} {:10s} {:s}".format(o, family, lib[o][family] ) )
117+ elif len(lib[o][family]) == 1:
118+ print ( "{:15s} {:10s} {:s}".format(o, family, lib[o][family][0] ) )
119+ else:
120+ print ( "{:15s} {:10s} {:d}".format(o, family, len(lib[o][family]) ) )
121+ """
122+
123+ from .gen_code import MappedObject
124+ for o in lib:
125+ out = header
126+ mapped = MappedObject(lib[o])
127+ out += mapped.gen_code()
128+ output_file = os.path.join(output_path, 'gen-%s.c' % o)
129+ with open(output_file, 'w') as f:
130+ f.write(out)
131+ print ("wrote %s" % output_file )
132+ sources_list.append(output_file)
133+
134+ out = header
135+ out += "#include \"aubio-generated.h\""
136+ check_types = "\n || ".join(["PyType_Ready(&Py_%sType) < 0" % o for o in lib])
137+ out += """
138+
139+int generated_types_ready (void)
140+{{
141+ return ({pycheck_types});
142+}}
143+""".format(pycheck_types = check_types)
144+
145+ add_types = "".join(["""
146+ Py_INCREF (&Py_{name}Type);
147+ PyModule_AddObject(m, "{name}", (PyObject *) & Py_{name}Type);""".format(name = o) for o in lib])
148+ out += """
149+
150+void add_generated_objects ( PyObject *m )
151+{{
152+{add_types}
153+}}
154+""".format(add_types = add_types)
155+
156+ output_file = os.path.join(output_path, 'aubio-generated.c')
157+ with open(output_file, 'w') as f:
158+ f.write(out)
159+ print ("wrote %s" % output_file )
160+ sources_list.append(output_file)
161+
162+ objlist = "".join(["extern PyTypeObject Py_%sType;\n" % p for p in lib])
163+ out = """
164+// generated list of objects created with gen_external.py
165+#include <Python.h>
166+
167+{objlist}
168+int generated_objects ( void );
169+void add_generated_objects( PyObject *m );
170+""".format(objlist = objlist)
171+
172+ output_file = os.path.join(output_path, 'aubio-generated.h')
173+ with open(output_file, 'w') as f:
174+ f.write(out)
175+ print ("wrote %s" % output_file )
176+ # no need to add header to list of sources
177+
178+ return sources_list
179+
180+if __name__ == '__main__':
181+ output_path = 'gen'
182+ generate_external(output_path)
python/lib/gen_pyobject.py+0−531
@@ -1,531 +0,0 @@
1−#! /usr/bin/python
2−
3−""" This madness of code is used to generate the C code of the python interface
4−to aubio. Don't try this at home.
5−
6−The list of typedefs and functions is obtained from the command line 'cpp
7−aubio.h'. This list is then used to parse all the functions about this object.
8−
9−I hear the ones asking "why not use swig, or cython, or something like that?"
10−
11−The requirements for this extension are the following:
12−
13− - aubio vectors can be viewed as numpy arrays, and vice versa
14− - aubio 'object' should be python classes, not just a bunch of functions
15−
16−I haven't met any python interface generator that can meet both these
17−requirements. If you know of one, please let me know, it will spare me
18−maintaining this bizarre file.
19−"""
20−
21−param_numbers = {
22− 'source': [0, 2],
23− 'sink': [2, 0],
24− 'sampler': [1, 1],
25−}
26−
27−# TODO
28−# do function: for now, only the following pattern is supported:
29−# void aubio_<foo>_do (aubio_foo_t * o,
30−# [input1_t * input, [output1_t * output, ..., output3_t * output]]);
31−# There is no way of knowing that output1 is actually input2. In the future,
32−# const could be used for the inputs in the C prototypes.
33−
34−def write_msg(*args):
35− pass
36− # uncomment out for debugging
37− #print args
38−
39−def split_type(arg):
40− """ arg = 'foo *name'
41− return ['foo*', 'name'] """
42− l = arg.split()
43− type_arg = {'type': l[0], 'name': l[1]}
44− # ['foo', '*name'] -> ['foo*', 'name']
45− if l[-1].startswith('*'):
46− #return [l[0]+'*', l[1][1:]]
47− type_arg['type'] = l[0] + '*'
48− type_arg['name'] = l[1][1:]
49− # ['foo', '*', 'name'] -> ['foo*', 'name']
50− if len(l) == 3:
51− #return [l[0]+l[1], l[2]]
52− type_arg['type'] = l[0]+l[1]
53− type_arg['name'] = l[2]
54− else:
55− #return l
56− pass
57− return type_arg
58−
59−def get_params(proto):
60− """ get the list of parameters from a function prototype
61− example: proto = "int main (int argc, char ** argv)"
62− returns: ['int argc', 'char ** argv']
63− """
64− import re
65− paramregex = re.compile('[\(, ](\w+ \*?\*? ?\w+)[, \)]')
66− return paramregex.findall(proto)
67−
68−def get_params_types_names(proto):
69− """ get the list of parameters from a function prototype
70− example: proto = "int main (int argc, char ** argv)"
71− returns: [['int', 'argc'], ['char **','argv']]
72− """
73− return list(map(split_type, get_params(proto)))
74−
75−def get_return_type(proto):
76− import re
77− paramregex = re.compile('(\w+ ?\*?).*')
78− outputs = paramregex.findall(proto)
79− assert len(outputs) == 1
80− return outputs[0].replace(' ', '')
81−
82−def get_name(proto):
83− name = proto.split()[1].split('(')[0]
84− return name.replace('*','')
85−
86−# the important bits: the size of the output for each objects. this data should
87−# move into the C library at some point.
88−defaultsizes = {
89− 'resampler': ['input->length * self->ratio'],
90− 'specdesc': ['1'],
91− 'onset': ['1'],
92− 'pitchyin': ['1'],
93− 'pitchyinfft': ['1'],
94− 'pitchschmitt': ['1'],
95− 'pitchmcomb': ['1'],
96− 'pitchfcomb': ['1'],
97− 'pitch': ['1'],
98− 'tss': ['self->buf_size', 'self->buf_size'],
99− 'mfcc': ['self->n_coeffs'],
100− 'beattracking': ['self->hop_size'],
101− 'tempo': ['1'],
102− 'peakpicker': ['1'],
103− 'source': ['self->hop_size', '1'],
104− 'sampler': ['self->hop_size'],
105− 'wavetable': ['self->hop_size'],
106−}
107−
108−# default value for variables
109−aubioinitvalue = {
110− 'uint_t': 0,
111− 'sint_t': 0,
112− 'smpl_t': 0,
113− 'lsmp_t': 0.,
114− 'char_t*': 'NULL',
115− }
116−
117−aubiodefvalue = {
118− # we have some clean up to do
119− 'buf_size': 'Py_default_vector_length',
120− # and here too
121− 'hop_size': 'Py_default_vector_length / 2',
122− # these should be alright
123− 'samplerate': 'Py_aubio_default_samplerate',
124− # now for the non obvious ones
125− 'n_filters': '40',
126− 'n_coeffs': '13',
127− 'nelems': '10',
128− 'flow': '0.',
129− 'fhig': '1.',
130− 'ilow': '0.',
131− 'ihig': '1.',
132− 'thrs': '0.5',
133− 'ratio': '0.5',
134− 'method': '"default"',
135− 'uri': '"none"',
136− }
137−
138−# aubio to python
139−aubio2pytypes = {
140− 'uint_t': 'I',
141− 'sint_t': 'I',
142− 'smpl_t': 'f',
143− 'lsmp_t': 'd',
144− 'fvec_t*': 'O',
145− 'cvec_t*': 'O',
146− 'char_t*': 's',
147−}
148−
149−# python to aubio
150−aubiovecfrompyobj = {
151− 'fvec_t*': 'PyAubio_ArrayToCFvec',
152− 'cvec_t*': 'PyAubio_ArrayToCCvec',
153− 'uint_t': '(uint_t)PyLong_AsLong',
154−}
155−
156−# aubio to python
157−aubiovectopyobj = {
158− 'fvec_t*': 'PyAubio_CFvecToArray',
159− 'cvec_t*': 'PyAubio_CCvecToPyCvec',
160− 'smpl_t': 'PyFloat_FromDouble',
161− 'uint_t*': 'PyLong_FromLong',
162− 'uint_t': 'PyLong_FromLong',
163−}
164−
165−def gen_new_init(newfunc, name):
166− newparams = get_params_types_names(newfunc)
167− # self->param1, self->param2, self->param3
168− if len(newparams):
169− selfparams = ', self->'+', self->'.join([p['name'] for p in newparams])
170− else:
171− selfparams = ''
172− # "param1", "param2", "param3"
173− paramnames = ", ".join(["\""+p['name']+"\"" for p in newparams])
174− pyparams = "".join([aubio2pytypes[p['type']] for p in newparams])
175− paramrefs = ", ".join(["&" + p['name'] for p in newparams])
176− s = """\
177−// WARNING: this file is generated, DO NOT EDIT
178−
179−// WARNING: if you haven't read the first line yet, please do so
180−#include "aubiowraphell.h"
181−
182−typedef struct
183−{
184− PyObject_HEAD
185− aubio_%(name)s_t * o;
186−""" % locals()
187− for p in newparams:
188− ptype = p['type']
189− pname = p['name']
190− s += """\
191− %(ptype)s %(pname)s;
192−""" % locals()
193− s += """\
194−} Py_%(name)s;
195−
196−static char Py_%(name)s_doc[] = "%(name)s object";
197−
198−static PyObject *
199−Py_%(name)s_new (PyTypeObject * pytype, PyObject * args, PyObject * kwds)
200−{
201− Py_%(name)s *self;
202−""" % locals()
203− for p in newparams:
204− ptype = p['type']
205− pname = p['name']
206− initval = aubioinitvalue[ptype]
207− s += """\
208− %(ptype)s %(pname)s = %(initval)s;
209−""" % locals()
210− # now the actual PyArg_Parse
211− if len(paramnames):
212− s += """\
213− static char *kwlist[] = { %(paramnames)s, NULL };
214−
215− if (!PyArg_ParseTupleAndKeywords (args, kwds, "|%(pyparams)s", kwlist,
216− %(paramrefs)s)) {
217− return NULL;
218− }
219−""" % locals()
220− s += """\
221−
222− self = (Py_%(name)s *) pytype->tp_alloc (pytype, 0);
223−
224− if (self == NULL) {
225− return NULL;
226− }
227−""" % locals()
228− for p in newparams:
229− ptype = p['type']
230− pname = p['name']
231− defval = aubiodefvalue[pname]
232− if ptype == 'char_t*':
233− s += """\
234−
235− self->%(pname)s = %(defval)s;
236− if (%(pname)s != NULL) {
237− self->%(pname)s = %(pname)s;
238− }
239−""" % locals()
240− elif ptype == 'uint_t':
241− s += """\
242−
243− self->%(pname)s = %(defval)s;
244− if ((sint_t)%(pname)s > 0) {
245− self->%(pname)s = %(pname)s;
246− } else if ((sint_t)%(pname)s < 0) {
247− PyErr_SetString (PyExc_ValueError,
248− "can not use negative value for %(pname)s");
249− return NULL;
250− }
251−""" % locals()
252− elif ptype == 'smpl_t':
253− s += """\
254−
255− self->%(pname)s = %(defval)s;
256− if (%(pname)s != %(defval)s) {
257− self->%(pname)s = %(pname)s;
258− }
259−""" % locals()
260− else:
261− write_msg ("ERROR, unknown type of parameter %s %s" % (ptype, pname) )
262− s += """\
263−
264− return (PyObject *) self;
265−}
266−
267−AUBIO_INIT(%(name)s %(selfparams)s)
268−
269−AUBIO_DEL(%(name)s)
270−
271−""" % locals()
272− return s
273−
274−def gen_do_input_params(inputparams):
275− inputdefs = ''
276− parseinput = ''
277− inputrefs = ''
278− inputvecs = ''
279− pytypes = ''
280−
281− if len(inputparams):
282− # build the parsing string for PyArg_ParseTuple
283− pytypes = "".join([aubio2pytypes[p['type']] for p in inputparams])
284−
285− inputdefs = " /* input vectors python prototypes */\n"
286− for p in inputparams:
287− if p['type'] != 'uint_t':
288− inputdefs += " PyObject * " + p['name'] + "_obj;\n"
289−
290− inputvecs = " /* input vectors prototypes */\n "
291− inputvecs += "\n ".join([ p['type'] + ' ' + p['name'] + ";" for p in inputparams])
292−
293− parseinput = " /* input vectors parsing */\n "
294− for p in inputparams:
295− inputvec = p['name']
296− if p['type'] != 'uint_t':
297− inputdef = p['name'] + "_obj"
298− else:
299− inputdef = p['name']
300− converter = aubiovecfrompyobj[p['type']]
301− if p['type'] != 'uint_t':
302− parseinput += """%(inputvec)s = %(converter)s (%(inputdef)s);
303−
304− if (%(inputvec)s == NULL) {
305− return NULL;
306− }
307−
308− """ % locals()
309−
310− # build the string for the input objects references
311− inputreflist = []
312− for p in inputparams:
313− if p['type'] != 'uint_t':
314− inputreflist += [ "&" + p['name'] + "_obj" ]
315− else:
316− inputreflist += [ "&" + p['name'] ]
317− inputrefs = ", ".join(inputreflist)
318− # end of inputs strings
319− return inputdefs, parseinput, inputrefs, inputvecs, pytypes
320−
321−def gen_do_output_params(outputparams, name):
322− outputvecs = ""
323− outputcreate = ""
324− if len(outputparams):
325− outputvecs = " /* output vectors prototypes */\n"
326− for p in outputparams:
327− params = {
328− 'name': p['name'], 'pytype': p['type'], 'autype': p['type'][:-3],
329− 'length': defaultsizes[name].pop(0) }
330− if (p['type'] == 'uint_t*'):
331− outputvecs += ' uint_t' + ' ' + p['name'] + ";\n"
332− outputcreate += " %(name)s = 0;\n" % params
333− else:
334− outputvecs += " " + p['type'] + ' ' + p['name'] + ";\n"
335− outputcreate += " /* creating output %(name)s as a new_%(autype)s of length %(length)s */\n" % params
336− outputcreate += " %(name)s = new_%(autype)s (%(length)s);\n" % params
337−
338− returnval = "";
339− if len(outputparams) > 1:
340− returnval += " PyObject *outputs = PyList_New(0);\n"
341− for p in outputparams:
342− returnval += " PyList_Append( outputs, (PyObject *)" + aubiovectopyobj[p['type']] + " (" + p['name'] + ")" +");\n"
343− returnval += " return outputs;"
344− elif len(outputparams) == 1:
345− if defaultsizes[name] == '1':
346− returnval += " return (PyObject *)PyFloat_FromDouble(" + p['name'] + "->data[0])"
347− else:
348− returnval += " return (PyObject *)" + aubiovectopyobj[p['type']] + " (" + p['name'] + ")"
349− else:
350− returnval += " Py_RETURN_NONE"
351− # end of output strings
352− return outputvecs, outputcreate, returnval
353−
354−def gen_do(dofunc, name):
355− funcname = dofunc.split()[1].split('(')[0]
356− doparams = get_params_types_names(dofunc)
357− # make sure the first parameter is the object
358− assert doparams[0]['type'] == "aubio_"+name+"_t*", \
359− "method is not in 'aubio_<name>_t"
360− # and remove it
361− doparams = doparams[1:]
362−
363− n_param = len(doparams)
364−
365− if name in list(param_numbers.keys()):
366− n_input_param, n_output_param = param_numbers[name]
367− else:
368− n_input_param, n_output_param = 1, n_param - 1
369−
370− assert n_output_param + n_input_param == n_param, "n_output_param + n_input_param != n_param for %s" % name
371−
372− inputparams = doparams[:n_input_param]
373− outputparams = doparams[n_input_param:n_input_param + n_output_param]
374−
375− inputdefs, parseinput, inputrefs, inputvecs, pytypes = gen_do_input_params(inputparams);
376− outputvecs, outputcreate, returnval = gen_do_output_params(outputparams, name)
377−
378− # build strings for outputs
379− # build the parameters for the _do() call
380− doparams_string = "self->o"
381− for p in doparams:
382− if p['type'] == 'uint_t*':
383− doparams_string += ", &" + p['name']
384− else:
385− doparams_string += ", " + p['name']
386−
387− if n_input_param:
388− arg_parse_tuple = """\
389− if (!PyArg_ParseTuple (args, "%(pytypes)s", %(inputrefs)s)) {
390− return NULL;
391− }
392−""" % locals()
393− else:
394− arg_parse_tuple = ""
395− # put it all together
396− s = """\
397−/* function Py_%(name)s_do */
398−static PyObject *
399−Py_%(name)s_do(Py_%(name)s * self, PyObject * args)
400−{
401−%(inputdefs)s
402−%(inputvecs)s
403−%(outputvecs)s
404−
405−%(arg_parse_tuple)s
406−
407−%(parseinput)s
408−
409−%(outputcreate)s
410−
411− /* compute _do function */
412− %(funcname)s (%(doparams_string)s);
413−
414−%(returnval)s;
415−}
416−""" % locals()
417− return s
418−
419−def gen_members(new_method, name):
420− newparams = get_params_types_names(new_method)
421− s = """
422−AUBIO_MEMBERS_START(%(name)s)""" % locals()
423− for param in newparams:
424− if param['type'] == 'char_t*':
425− s += """
426− {"%(pname)s", T_STRING, offsetof (Py_%(name)s, %(pname)s), READONLY, ""},""" \
427− % { 'pname': param['name'], 'ptype': param['type'], 'name': name}
428− elif param['type'] == 'uint_t':
429− s += """
430− {"%(pname)s", T_INT, offsetof (Py_%(name)s, %(pname)s), READONLY, ""},""" \
431− % { 'pname': param['name'], 'ptype': param['type'], 'name': name}
432− elif param['type'] == 'smpl_t':
433− s += """
434− {"%(pname)s", T_FLOAT, offsetof (Py_%(name)s, %(pname)s), READONLY, ""},""" \
435− % { 'pname': param['name'], 'ptype': param['type'], 'name': name}
436− else:
437− write_msg ("-- ERROR, unknown member type ", param )
438− s += """
439−AUBIO_MEMBERS_STOP(%(name)s)
440−
441−""" % locals()
442− return s
443−
444−
445−def gen_methods(get_methods, set_methods, name):
446− s = ""
447− method_defs = ""
448− for method in set_methods:
449− method_name = get_name(method)
450− params = get_params_types_names(method)
451− out_type = get_return_type(method)
452− assert params[0]['type'] == "aubio_"+name+"_t*", \
453− "get method is not in 'aubio_<name>_t"
454− write_msg (method )
455− write_msg (params[1:])
456− setter_args = "self->o, " +",".join([p['name'] for p in params[1:]])
457− parse_args = ""
458− for p in params[1:]:
459− parse_args += p['type'] + " " + p['name'] + ";\n"
460− argmap = "".join([aubio2pytypes[p['type']] for p in params[1:]])
461− arglist = ", ".join(["&"+p['name'] for p in params[1:]])
462− parse_args += """
463− if (!PyArg_ParseTuple (args, "%(argmap)s", %(arglist)s)) {
464− return NULL;
465− } """ % locals()
466− s += """
467−static PyObject *
468−Py%(funcname)s (Py_%(objname)s *self, PyObject *args)
469−{
470− uint_t err = 0;
471−
472− %(parse_args)s
473−
474− err = %(funcname)s (%(setter_args)s);
475−
476− if (err > 0) {
477− PyErr_SetString (PyExc_ValueError,
478− "error running %(funcname)s");
479− return NULL;
480− }
481− Py_RETURN_NONE;
482−}
483−""" % {'funcname': method_name, 'objname': name,
484− 'out_type': out_type, 'setter_args': setter_args, 'parse_args': parse_args }
485− shortname = method_name.split('aubio_'+name+'_')[-1]
486− method_defs += """\
487− {"%(shortname)s", (PyCFunction) Py%(method_name)s,
488− METH_VARARGS, ""},
489−""" % locals()
490−
491− for method in get_methods:
492− method_name = get_name(method)
493− params = get_params_types_names(method)
494− out_type = get_return_type(method)
495− assert params[0]['type'] == "aubio_"+name+"_t*", \
496− "get method is not in 'aubio_<name>_t %s" % params[0]['type']
497− assert len(params) == 1, \
498− "get method has more than one parameter %s" % params
499− getter_args = "self->o"
500− returnval = "(PyObject *)" + aubiovectopyobj[out_type] + " (tmp)"
501− shortname = method_name.split('aubio_'+name+'_')[-1]
502− method_defs += """\
503− {"%(shortname)s", (PyCFunction) Py%(method_name)s,
504− METH_NOARGS, ""},
505−""" % locals()
506− s += """
507−static PyObject *
508−Py%(funcname)s (Py_%(objname)s *self, PyObject *unused)
509−{
510− %(out_type)s tmp = %(funcname)s (%(getter_args)s);
511− return %(returnval)s;
512−}
513−""" % {'funcname': method_name, 'objname': name,
514− 'out_type': out_type, 'getter_args': getter_args, 'returnval': returnval }
515−
516− s += """
517−static PyMethodDef Py_%(name)s_methods[] = {
518−""" % locals()
519− s += method_defs
520− s += """\
521− {NULL} /* sentinel */
522−};
523−""" % locals()
524− return s
525−
526−def gen_finish(name):
527− s = """\
528−
529−AUBIO_TYPEOBJECT(%(name)s, "aubio.%(name)s")
530−""" % locals()
531− return s
python/lib/generator.py+0−233
@@ -1,233 +0,0 @@
1−#! /usr/bin/python
2−
3−""" This file generates a c file from a list of cpp prototypes. """
4−
5−import os, sys, shutil
6−from .gen_pyobject import write_msg, gen_new_init, gen_do, gen_members, gen_methods, gen_finish
7−
8−def get_cpp_objects():
9−
10− cpp_output = [l.strip() for l in os.popen('cpp -DAUBIO_UNSTABLE=1 -I../build/src ../src/aubio.h').readlines()]
11−
12− cpp_output = filter(lambda y: len(y) > 1, cpp_output)
13− cpp_output = filter(lambda y: not y.startswith('#'), cpp_output)
14− cpp_output = list(cpp_output)
15−
16− i = 1
17− while 1:
18− if i >= len(cpp_output): break
19− if cpp_output[i-1].endswith(',') or cpp_output[i-1].endswith('{') or cpp_output[i].startswith('}'):
20− cpp_output[i] = cpp_output[i-1] + ' ' + cpp_output[i]
21− cpp_output.pop(i-1)
22− else:
23− i += 1
24−
25− typedefs = filter(lambda y: y.startswith ('typedef struct _aubio'), cpp_output)
26− typedefs = list(typedefs)
27−
28− cpp_objects = [a.split()[3][:-1] for a in typedefs]
29−
30− return cpp_output, cpp_objects
31−
32−def generate_object_files(output_path):
33− if os.path.isdir(output_path): shutil.rmtree(output_path)
34− os.mkdir(output_path)
35−
36− generated_objects = []
37− cpp_output, cpp_objects = get_cpp_objects()
38− skip_objects = [
39− # already in ext/
40− 'fft',
41− 'pvoc',
42− 'filter',
43− 'filterbank',
44− #'resampler',
45− # AUBIO_UNSTABLE
46− 'hist',
47− 'parameter',
48− 'scale',
49− 'beattracking',
50− 'resampler',
51− 'sndfile',
52− 'peakpicker',
53− 'pitchfcomb',
54− 'pitchmcomb',
55− 'pitchschmitt',
56− 'pitchspecacf',
57− 'pitchyin',
58− 'pitchyinfft',
59− 'sink',
60− 'sink_apple_audio',
61− 'sink_sndfile',
62− 'sink_wavwrite',
63− 'source',
64− 'source_apple_audio',
65− 'source_sndfile',
66− 'source_avcodec',
67− 'source_wavread',
68− #'sampler',
69− 'audio_unit',
70− ]
71−
72− write_msg("-- INFO: %d objects in total" % len(cpp_objects))
73−
74− for this_object in cpp_objects:
75− lint = 0
76−
77− if this_object[-2:] == '_t':
78− object_name = this_object[:-2]
79− else:
80− object_name = this_object
81− write_msg("-- WARNING: %s does not end in _t" % this_object)
82−
83− if object_name[:len('aubio_')] != 'aubio_':
84− write_msg("-- WARNING: %s does not start n aubio_" % this_object)
85−
86− write_msg("-- INFO: looking at", object_name)
87− object_methods = filter(lambda x: this_object in x, cpp_output)
88− object_methods = [a.strip() for a in object_methods]
89− object_methods = filter(lambda x: not x.startswith('typedef'), object_methods)
90− object_methods = list(object_methods)
91− #for method in object_methods:
92− # write_msg(method)
93− new_methods = list(filter(
94− lambda x: 'new_'+object_name in x, object_methods))
95− if len(new_methods) > 1:
96− write_msg("-- WARNING: more than one new method for", object_name)
97− for method in new_methods:
98− write_msg(method)
99− elif len(new_methods) < 1:
100− write_msg("-- WARNING: no new method for", object_name)
101− elif 0:
102− for method in new_methods:
103− write_msg(method)
104−
105− del_methods = list(filter(
106− lambda x: 'del_'+object_name in x, object_methods))
107− if len(del_methods) > 1:
108− write_msg("-- WARNING: more than one del method for", object_name)
109− for method in del_methods:
110− write_msg(method)
111− elif len(del_methods) < 1:
112− write_msg("-- WARNING: no del method for", object_name)
113−
114− do_methods = list(filter(
115− lambda x: object_name+'_do' in x, object_methods))
116− if len(do_methods) > 1:
117− pass
118− #write_msg("-- WARNING: more than one do method for", object_name)
119− #for method in do_methods:
120− # write_msg(method)
121− elif len(do_methods) < 1:
122− write_msg("-- WARNING: no do method for", object_name)
123− elif 0:
124− for method in do_methods:
125− write_msg(method)
126−
127− # check do methods return void
128− for method in do_methods:
129− if (method.split()[0] != 'void'):
130− write_msg("-- ERROR: _do method does not return void:", method )
131−
132− get_methods = filter(lambda x: object_name+'_get_' in x, object_methods)
133−
134− set_methods = filter(lambda x: object_name+'_set_' in x, object_methods)
135− for method in set_methods:
136− if (method.split()[0] != 'uint_t'):
137− write_msg("-- ERROR: _set method does not return uint_t:", method )
138−
139− other_methods = filter(lambda x: x not in new_methods, object_methods)
140− other_methods = filter(lambda x: x not in del_methods, other_methods)
141− other_methods = filter(lambda x: x not in do_methods, other_methods)
142− other_methods = filter(lambda x: x not in get_methods, other_methods)
143− other_methods = filter(lambda x: x not in set_methods, other_methods)
144− other_methods = list(other_methods)
145−
146− if len(other_methods) > 0:
147− write_msg("-- WARNING: some methods for", object_name, "were unidentified")
148− for method in other_methods:
149− write_msg(method)
150−
151−
152− # generate this_object
153− short_name = object_name[len('aubio_'):]
154− if short_name in skip_objects:
155− write_msg("-- INFO: skipping object", short_name )
156− continue
157− if 1: #try:
158− s = gen_new_init(new_methods[0], short_name)
159− s += gen_do(do_methods[0], short_name)
160− s += gen_members(new_methods[0], short_name)
161− s += gen_methods(get_methods, set_methods, short_name)
162− s += gen_finish(short_name)
163− generated_filepath = os.path.join(output_path,'gen-'+short_name+'.c')
164− fd = open(generated_filepath, 'w')
165− fd.write(s)
166− #except Exception, e:
167− # write_msg("-- ERROR:", type(e), str(e), "in", short_name)
168− # continue
169− generated_objects += [this_object]
170−
171− s = """// generated list of objects created with generator.py
172−
173−"""
174−
175− types_ready = []
176− for each in generated_objects:
177− types_ready.append(" PyType_Ready (&Py_%sType) < 0" % \
178− each.replace('aubio_','').replace('_t','') )
179−
180− s = """// generated list of objects created with generator.py
181−
182−#include "aubio-generated.h"
183−"""
184−
185− s += """
186−int generated_types_ready (void)
187−{
188− return (
189−"""
190− s += ('\n ||').join(types_ready)
191− s += """);
192−}
193−"""
194−
195− s += """
196−void add_generated_objects ( PyObject *m )
197−{"""
198− for each in generated_objects:
199− s += """
200− Py_INCREF (&Py_%(name)sType);
201− PyModule_AddObject (m, "%(name)s", (PyObject *) & Py_%(name)sType);""" % \
202− { 'name': ( each.replace('aubio_','').replace('_t','') ) }
203−
204− s += """
205−}"""
206−
207− fd = open(os.path.join(output_path,'aubio-generated.c'), 'w')
208− fd.write(s)
209−
210− s = """// generated list of objects created with generator.py
211−
212−#include <Python.h>
213−
214−"""
215−
216− for each in generated_objects:
217− s += "extern PyTypeObject Py_%sType;\n" % \
218− each.replace('aubio_','').replace('_t','')
219−
220− s+= "int generated_objects ( void );\n"
221− s+= "void add_generated_objects( PyObject *m );\n"
222−
223− fd = open(os.path.join(output_path,'aubio-generated.h'), 'w')
224− fd.write(s)
225−
226− from os import listdir
227− generated_files = listdir(output_path)
228− generated_files = filter(lambda x: x.endswith('.c'), generated_files)
229− generated_files = [output_path+'/'+f for f in generated_files]
230− return generated_files
231−
232−if __name__ == '__main__':
233− generate_object_files('gen')

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t