source: python/lib/generator.py @ f1100a4

feature/autosinkfeature/constantqfeature/pitchshiftfeature/pydocstringsfeature/timestretchpitchshiftsamplertimestretchyinfft+
Last change on this file since f1100a4 was f1100a4, checked in by Paul Brossier <piem@piem.org>, 6 years ago

ext/py-sink.c: do not generate

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