source: python/lib/generator.py @ 333eec1

feature/autosinkfeature/cnnfeature/cnn_orgfeature/constantqfeature/crepefeature/crepe_orgfeature/pitchshiftfeature/pydocstringsfeature/timestretchfix/ffmpeg5pitchshiftsamplertimestretchyinfft+
Last change on this file since 333eec1 was 333eec1, checked in by Paul Brossier <piem@piem.org>, 8 years ago

python/lib/generator.py: prepare for python3

  • Property mode set to 100755
File size: 7.2 KB
Line 
1#! /usr/bin/python
2
3""" This file generates a c file from a list of cpp prototypes. """
4
5import os, sys, shutil
6from .gen_pyobject import write_msg, gen_new_init, gen_do, gen_members, gen_methods, gen_finish
7
8def 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
32def 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 += """
186int generated_types_ready (void)
187{
188  return (
189"""
190  s += ('\n     ||').join(types_ready)
191  s += """);
192}
193"""
194
195  s += """
196void 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
232if __name__ == '__main__':
233  generate_object_files('gen')
Note: See TracBrowser for help on using the repository browser.