7 buf
= strip_comments(buf
)
8 pat
= re
.compile(r
"""\\\n""", re
.MULTILINE
)
10 pat
= re
.compile(r
"""^[#].*?$""", re
.MULTILINE
)
12 pat
= re
.compile(r
"""^(typedef|struct|enum)(\s|.|\n)*?;\s*""", re
.MULTILINE
)
14 pat
= re
.compile(r
"""\s+""", re
.MULTILINE
)
15 buf
= pat
.sub(' ',buf
)
16 pat
= re
.compile(r
""";\s*""", re
.MULTILINE
)
17 buf
= pat
.sub('\n',buf
)
19 #pat=re.compile(r'\s+([*|&]+)\s*(\w+)')
20 pat
= re
.compile(r
' \s+ ([*|&]+) \s* (\w+)',re
.VERBOSE
)
21 buf
= pat
.sub(r
'\1 \2', buf
)
22 pat
= re
.compile(r
'\s+ (\w+) \[ \s* \]',re
.VERBOSE
)
23 buf
= pat
.sub(r
'[] \1', buf
)
24 # buf = string.replace(buf, 'G_CONST_RETURN ', 'const-')
25 buf
= string
.replace(buf
, 'const ', '')
28 def strip_comments(buf
):
32 pos
= string
.find(buf
, '/*', lastpos
)
34 parts
.append(buf
[lastpos
:pos
])
35 pos
= string
.find(buf
, '*/', pos
)
41 parts
.append(buf
[lastpos
:])
43 return string
.join(parts
, '')
47 buf
= strip_comments(buf
)
48 buf
= re
.sub('\n', ' ', buf
)
50 enum_pat
= re
.compile(r
'enum\s*{([^}]*)}\s*([A-Z][A-Za-z]*)(\s|;)')
51 splitter
= re
.compile(r
'\s*,\s', re
.MULTILINE
)
54 m
= enum_pat
.search(buf
, pos
)
59 isflags
= string
.find(vals
, '<<') >= 0
61 for val
in splitter
.split(vals
):
62 if not string
.strip(val
): continue
63 entries
.append(string
.split(val
)[0])
64 enums
.append((name
, isflags
, entries
))
69 #typedef unsigned int dbus_bool_t;
73 #typedef struct FooStruct FooStruct;
74 # typedef void (* DBusAddWatchFunction) (DBusWatch *watch,
77 def find_typedefs(buf
):
79 buf
= re
.sub('\n', ' ', strip_comments(buf
))
80 typedef_pat
= re
.compile(
81 r
"""typedef\s*(?P<type>\w*)
83 ([(]\s*\*\s*(?P<callback>[\w* ]*)[)]|{([^}]*)}|)
85 (?P<args1>[(](?P<args2>[\s\w*,_]*)[)]|[\w ]*)""",
86 re
.MULTILINE | re
.VERBOSE
)
87 pat
= re
.compile(r
"""\s+""", re
.MULTILINE
)
90 m
= typedef_pat
.search(buf
, pos
)
93 if m
.group('type') == 'enum':
96 if m
.group('args2') != None:
97 args
= pat
.sub(' ', m
.group('args2'))
99 current
= '%s (* %s) (%s)' % (m
.group('type'),
103 current
= '%s %s' % (m
.group('type'), m
.group('args1'))
104 typedefs
.append(current
)
108 proto_pat
= re
.compile(r
"""
109 (?P<ret>(-|\w|\&|\*|\s)+\s*) # return type
110 \s+ # skip whitespace
111 (?P<func>\w+)\s*[(] # match the function name until the opening (
112 (?P<args>.*?)[)] # group the function arguments
113 """, re
.IGNORECASE|re
.VERBOSE
)
114 arg_split_pat
= re
.compile("\s*,\s*")
117 def find_functions(buf
):
119 buf
= clean_func(buf
)
120 buf
= string
.split(buf
,'\n')
124 m
= proto_pat
.match(p
)
128 func
= m
.group('func')
130 args
= m
.group('args')
131 args
= arg_split_pat
.split(args
)
132 # for i in range(len(args)):
133 # spaces = string.count(args[i], ' ')
135 # args[i] = string.replace(args[i], ' ', '-', spaces - 1)
137 functions
.append((func
, ret
, args
))
141 def __init__(self
, filename
, enums
, typedefs
, functions
):
142 if not (enums
or typedefs
or functions
):
144 print 'cdef extern from "%s":' % filename
146 self
.output_enums(enums
)
147 self
.output_typedefs(typedefs
)
148 self
.output_functions(functions
)
153 def output_enums(self
, enums
):
155 print ' ctypedef enum %s:' % enum
[0]
163 # print ' %s = 1 << %d' % (item, i)
166 def output_typedefs(self
, typedefs
):
167 for typedef
in typedefs
:
168 if typedef
.find('va_list') != -1:
171 parts
= typedef
.split()
172 if parts
[0] == 'struct':
173 if parts
[-2] == parts
[-1]:
175 print ' ctypedef %s' % ' '.join(parts
)
177 print ' ctypedef %s' % typedef
179 def output_functions(self
, functions
):
180 for func
, ret
, args
in functions
:
184 str = ', '.join(args
)
185 if str.find('...') != -1:
187 if str.find('va_list') != -1:
189 if str.strip() == 'void':
191 print ' %-20s %s (%s)' % (ret
, func
, str)
193 def do_buffer(name
, buffer):
194 functions
= find_functions(buffer)
195 typedefs
= find_typedefs(buffer)
196 enums
= find_enums(buffer)
198 Writer(name
, enums
, typedefs
, functions
)
200 def do_header(filename
, name
=None):
205 for line
in open(filename
).readlines():
210 print '# -- %s -- ' % filename
211 do_buffer(name
, buffer)
213 def main(filename
, flags
, output
=None):
215 if output
is not None:
216 old_stdout
= sys
.stdout
219 if filename
.endswith('.h'):
223 cppflags
= ' '.join(flags
)
227 match
= re
.match('#include [<"]([^">]+)[">]$', line
)
230 filename
= match
.group(1)
231 print >>sys
.stderr
, "matched %s" % (filename
)
232 command
= "echo '%s'|cpp %s" % (line
, cppflags
)
233 output
= commands
.getoutput(command
)
234 print >>sys
.stderr
, "output %s" % (output
)
235 do_buffer(filename
, output
)
240 if old_stdout
is not None:
241 sys
.stdout
= old_stdout
243 if __name__
== '__main__':
244 main(sys
.argv
[1], sys
.argv
[2:])