generator.py: update skip list
[aubio.git] / interfaces / python / generator.py
1 #! /usr/bin/python
2
3 """ This file generates a c file from a list of cpp prototypes. """
4
5 import os, sys
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
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
30 def generate_object_files():
31
32   generated_objects = []
33   cpp_output, cpp_objects = get_cpp_objects()
34   skip_objects = ['fft',
35       'pvoc',
36       'filter',
37       'filterbank',
38       'resampler',
39       'sndfile',
40       'sink',
41       'source_apple_audio',
42       'source_sndfile']
43
44   write_msg("-- INFO: %d objects in total" % len(cpp_objects))
45
46   for this_object in cpp_objects:
47       lint = 0
48    
49       if this_object[-2:] == '_t':
50           object_name = this_object[:-2]
51       else:
52           object_name = this_object
53           write_msg("-- WARNING: %s does not end in _t" % this_object)
54
55       if object_name[:len('aubio_')] != 'aubio_':
56           write_msg("-- WARNING: %s does not start n aubio_" % this_object)
57
58       write_msg("-- INFO: looking at", object_name)
59       object_methods = filter(lambda x: this_object in x, cpp_output)
60       object_methods = [a.strip() for a in object_methods]
61       object_methods = filter(lambda x: not x.startswith('typedef'), object_methods)
62       #for method in object_methods:
63       #    write_msg(method)
64       new_methods = filter(lambda x: 'new_'+object_name in x, object_methods)
65       if len(new_methods) > 1:
66           write_msg("-- WARNING: more than one new method for", object_name)
67           for method in new_methods:
68               write_msg(method)
69       elif len(new_methods) < 1:
70           write_msg("-- WARNING: no new method for", object_name)
71       elif 0:
72           for method in new_methods:
73               write_msg(method)
74
75       del_methods = filter(lambda x: 'del_'+object_name in x, object_methods)
76       if len(del_methods) > 1:
77           write_msg("-- WARNING: more than one del method for", object_name)
78           for method in del_methods:
79               write_msg(method)
80       elif len(del_methods) < 1:
81           write_msg("-- WARNING: no del method for", object_name)
82
83       do_methods = filter(lambda x: object_name+'_do' in x, object_methods)
84       if len(do_methods) > 1:
85           pass
86           #write_msg("-- WARNING: more than one do method for", object_name)
87           #for method in do_methods:
88           #    write_msg(method)
89       elif len(do_methods) < 1:
90           write_msg("-- WARNING: no do method for", object_name)
91       elif 0:
92           for method in do_methods:
93               write_msg(method)
94
95       # check do methods return void
96       for method in do_methods:
97           if (method.split()[0] != 'void'):
98               write_msg("-- ERROR: _do method does not return void:", method )
99
100       get_methods = filter(lambda x: object_name+'_get_' in x, object_methods)
101
102       set_methods = filter(lambda x: object_name+'_set_' in x, object_methods)
103       for method in set_methods:
104           if (method.split()[0] != 'uint_t'):
105               write_msg("-- ERROR: _set method does not return uint_t:", method )
106
107       other_methods = filter(lambda x: x not in new_methods, object_methods)
108       other_methods = filter(lambda x: x not in del_methods, other_methods)
109       other_methods = filter(lambda x: x not in    do_methods, other_methods)
110       other_methods = filter(lambda x: x not in get_methods, other_methods)
111       other_methods = filter(lambda x: x not in set_methods, other_methods)
112
113       if len(other_methods) > 0:
114           write_msg("-- WARNING: some methods for", object_name, "were unidentified")
115           for method in other_methods:
116               write_msg(method)
117
118
119       # generate this_object
120       if not os.path.isdir('generated'): os.mkdir('generated')
121       short_name = object_name[len('aubio_'):]
122       if short_name in skip_objects:
123               write_msg("-- INFO: skipping object", short_name )
124               continue
125       if 1: #try:
126           s = gen_new_init(new_methods[0], short_name)
127           s += gen_do(do_methods[0], short_name) 
128           s += gen_members(new_methods[0], short_name)
129           s += gen_methods(get_methods, set_methods, short_name)
130           s += gen_finish(short_name)
131           generated_filepath = 'generated/gen-'+short_name+'.c'
132           fd = open(generated_filepath, 'w')
133           fd.write(s)
134       #except Exception, e:
135       #        write_msg("-- ERROR:", type(e), str(e), "in", short_name)
136       #        continue
137       generated_objects += [this_object]
138
139   s = """// generated list of objects created with generator.py
140
141 """
142
143   for each in generated_objects:
144       s += "extern PyTypeObject Py_%sType;\n" % \
145               each.replace('aubio_','').replace('_t','')
146
147   types_ready = []
148   for each in generated_objects:
149       types_ready.append("  PyType_Ready (&Py_%sType) < 0" % \
150               each.replace('aubio_','').replace('_t','') )
151
152   s += """
153   int
154   generated_types_ready (void)
155   {
156     return (
157   """
158   s += ('\n     ||').join(types_ready)
159   s += """);
160   }
161   """
162
163   s += """
164   void
165   add_generated_objects ( PyObject *m )
166   {"""
167   for each in generated_objects:
168       s += """  Py_INCREF (&Py_%(name)sType);
169     PyModule_AddObject (m, "%(name)s", (PyObject *) & Py_%(name)sType);""" % \
170             { 'name': ( each.replace('aubio_','').replace('_t','') ) }
171
172   s += """
173   }"""
174
175   fd = open('generated/aubio-generated.h', 'w')
176   fd.write(s)
177
178   from os import listdir
179   generated_files = listdir('generated')
180   generated_files = filter(lambda x: x.endswith('.c'), generated_files)
181   generated_files = ['generated/'+f for f in generated_files]
182   return generated_files
183
184 if __name__ == '__main__':
185   generate_object_files()