source: python/lib/generator.py @ 8b8a020

feature/autosinkfeature/cnnfeature/cnn_orgfeature/constantqfeature/crepefeature/crepe_orgfeature/pitchshiftfeature/pydocstringsfeature/timestretchfix/ffmpeg5pitchshiftsamplertimestretchyinfft+
Last change on this file since 8b8a020 was 8b8a020, checked in by Nils Philippsen <nils@tiptoe.de>, 8 years ago

Python 3: coerce iterators into lists where necessary

  • 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
27  cpp_objects = [a.split()[3][:-1] for a in typedefs]
28
29  return cpp_output, cpp_objects
30
31def generate_object_files(output_path):
32  if os.path.isdir(output_path): shutil.rmtree(output_path)
33  os.mkdir(output_path)
34
35  generated_objects = []
36  cpp_output, cpp_objects = get_cpp_objects()
37  skip_objects = [
38      # already in ext/
39      'fft',
40      'pvoc',
41      'filter',
42      'filterbank',
43      #'resampler',
44      # AUBIO_UNSTABLE
45      'hist',
46      'parameter',
47      'scale',
48      'beattracking',
49      'resampler',
50      'sndfile',
51      'peakpicker',
52      'pitchfcomb',
53      'pitchmcomb',
54      'pitchschmitt',
55      'pitchspecacf',
56      'pitchyin',
57      'pitchyinfft',
58      'sink',
59      'sink_apple_audio',
60      'sink_sndfile',
61      'sink_wavwrite',
62      'source',
63      'source_apple_audio',
64      'source_sndfile',
65      'source_avcodec',
66      'source_wavread',
67      #'sampler',
68      'audio_unit',
69      ]
70
71  write_msg("-- INFO: %d objects in total" % len(cpp_objects))
72
73  for this_object in cpp_objects:
74      lint = 0
75
76      if this_object[-2:] == '_t':
77          object_name = this_object[:-2]
78      else:
79          object_name = this_object
80          write_msg("-- WARNING: %s does not end in _t" % this_object)
81
82      if object_name[:len('aubio_')] != 'aubio_':
83          write_msg("-- WARNING: %s does not start n aubio_" % this_object)
84
85      write_msg("-- INFO: looking at", object_name)
86      object_methods = filter(lambda x: this_object in x, cpp_output)
87      object_methods = [a.strip() for a in object_methods]
88      object_methods = filter(lambda x: not x.startswith('typedef'), object_methods)
89      object_methods = list(object_methods)
90      #for method in object_methods:
91      #    write_msg(method)
92      new_methods = list(filter(
93          lambda x: 'new_'+object_name in x, object_methods))
94      if len(new_methods) > 1:
95          write_msg("-- WARNING: more than one new method for", object_name)
96          for method in new_methods:
97              write_msg(method)
98      elif len(new_methods) < 1:
99          write_msg("-- WARNING: no new method for", object_name)
100      elif 0:
101          for method in new_methods:
102              write_msg(method)
103
104      del_methods = list(filter(
105          lambda x: 'del_'+object_name in x, object_methods))
106      if len(del_methods) > 1:
107          write_msg("-- WARNING: more than one del method for", object_name)
108          for method in del_methods:
109              write_msg(method)
110      elif len(del_methods) < 1:
111          write_msg("-- WARNING: no del method for", object_name)
112
113      do_methods = list(filter(
114          lambda x: object_name+'_do' in x, object_methods))
115      if len(do_methods) > 1:
116          pass
117          #write_msg("-- WARNING: more than one do method for", object_name)
118          #for method in do_methods:
119          #    write_msg(method)
120      elif len(do_methods) < 1:
121          write_msg("-- WARNING: no do method for", object_name)
122      elif 0:
123          for method in do_methods:
124              write_msg(method)
125
126      # check do methods return void
127      for method in do_methods:
128          if (method.split()[0] != 'void'):
129              write_msg("-- ERROR: _do method does not return void:", method )
130
131      get_methods = filter(lambda x: object_name+'_get_' in x, object_methods)
132
133      set_methods = filter(lambda x: object_name+'_set_' in x, object_methods)
134      for method in set_methods:
135          if (method.split()[0] != 'uint_t'):
136              write_msg("-- ERROR: _set method does not return uint_t:", method )
137
138      other_methods = filter(lambda x: x not in new_methods, object_methods)
139      other_methods = filter(lambda x: x not in del_methods, other_methods)
140      other_methods = filter(lambda x: x not in    do_methods, other_methods)
141      other_methods = filter(lambda x: x not in get_methods, other_methods)
142      other_methods = filter(lambda x: x not in set_methods, other_methods)
143      other_methods = list(other_methods)
144
145      if len(other_methods) > 0:
146          write_msg("-- WARNING: some methods for", object_name, "were unidentified")
147          for method in other_methods:
148              write_msg(method)
149
150
151      # generate this_object
152      short_name = object_name[len('aubio_'):]
153      if short_name in skip_objects:
154              write_msg("-- INFO: skipping object", short_name )
155              continue
156      if 1: #try:
157          s = gen_new_init(new_methods[0], short_name)
158          s += gen_do(do_methods[0], short_name)
159          s += gen_members(new_methods[0], short_name)
160          s += gen_methods(get_methods, set_methods, short_name)
161          s += gen_finish(short_name)
162          generated_filepath = os.path.join(output_path,'gen-'+short_name+'.c')
163          fd = open(generated_filepath, 'w')
164          fd.write(s)
165      #except Exception, e:
166      #        write_msg("-- ERROR:", type(e), str(e), "in", short_name)
167      #        continue
168      generated_objects += [this_object]
169
170  s = """// generated list of objects created with generator.py
171
172"""
173
174  types_ready = []
175  for each in generated_objects:
176      types_ready.append("  PyType_Ready (&Py_%sType) < 0" % \
177              each.replace('aubio_','').replace('_t','') )
178
179  s = """// generated list of objects created with generator.py
180
181#include "aubio-generated.h"
182"""
183
184  s += """
185int generated_types_ready (void)
186{
187  return (
188"""
189  s += ('\n     ||').join(types_ready)
190  s += """);
191}
192"""
193
194  s += """
195void add_generated_objects ( PyObject *m )
196{"""
197  for each in generated_objects:
198    s += """
199  Py_INCREF (&Py_%(name)sType);
200  PyModule_AddObject (m, "%(name)s", (PyObject *) & Py_%(name)sType);""" % \
201          { 'name': ( each.replace('aubio_','').replace('_t','') ) }
202
203  s += """
204}"""
205
206  fd = open(os.path.join(output_path,'aubio-generated.c'), 'w')
207  fd.write(s)
208
209  s = """// generated list of objects created with generator.py
210
211#include <Python.h>
212
213"""
214
215  for each in generated_objects:
216      s += "extern PyTypeObject Py_%sType;\n" % \
217              each.replace('aubio_','').replace('_t','')
218
219  s+= "int generated_objects ( void );\n"
220  s+= "void add_generated_objects( PyObject *m );\n"
221
222  fd = open(os.path.join(output_path,'aubio-generated.h'), 'w')
223  fd.write(s)
224
225  from os import listdir
226  generated_files = listdir(output_path)
227  generated_files = filter(lambda x: x.endswith('.c'), generated_files)
228  generated_files = [output_path+'/'+f for f in generated_files]
229  return generated_files
230
231if __name__ == '__main__':
232  generate_object_files('gen')
Note: See TracBrowser for help on using the repository browser.