9 buf = strip_comments(buf)
10 pat = re.compile(r"""\\\n""", re.MULTILINE)
12 pat = re.compile(r"""^[#].*?$""", re.MULTILINE)
14 pat = re.compile(r"""^(typedef|struct|enum)(\s|.|\n)*?;\s*""", re.MULTILINE)
16 pat = re.compile(r"""\s+""", re.MULTILINE)
17 buf = pat.sub(' ',buf)
18 pat = re.compile(r""";\s*""", re.MULTILINE)
19 buf = pat.sub('\n',buf)
21 #pat=re.compile(r'\s+([*|&]+)\s*(\w+)')
22 pat = re.compile(r' \s+ ([*|&]+) \s* (\w+)',re.VERBOSE)
23 buf = pat.sub(r'\1 \2', buf)
24 pat = re.compile(r'\s+ (\w+) \[ \s* \]',re.VERBOSE)
25 buf = pat.sub(r'[] \1', buf)
26 # buf = string.replace(buf, 'G_CONST_RETURN ', 'const-')
27 buf = string.replace(buf, 'const ', '')
30 def strip_comments(buf):
34 pos = string.find(buf, '/*', lastpos)
36 parts.append(buf[lastpos:pos])
37 pos = string.find(buf, '*/', pos)
43 parts.append(buf[lastpos:])
45 return string.join(parts, '')
49 buf = strip_comments(buf)
50 buf = re.sub('\n', ' ', buf)
52 enum_pat = re.compile(r'enum\s*{([^}]*)}\s*([A-Z][A-Za-z]*)(\s|;)')
53 splitter = re.compile(r'\s*,\s', re.MULTILINE)
56 m = enum_pat.search(buf, pos)
61 isflags = string.find(vals, '<<') >= 0
63 for val in splitter.split(vals):
64 if not string.strip(val): continue
65 entries.append(string.split(val)[0])
66 enums.append((name, isflags, entries))
71 #typedef unsigned int dbus_bool_t;
75 #typedef struct FooStruct FooStruct;
76 # typedef void (* DBusAddWatchFunction) (DBusWatch *watch,
79 def find_typedefs(buf):
81 buf = re.sub('\n', ' ', strip_comments(buf))
82 typedef_pat = re.compile(
83 r"""typedef\s*(?P<type>\w*)
85 ([(]\s*\*\s*(?P<callback>[\w* ]*)[)]|{([^}]*)}|)
87 (?P<args1>[(](?P<args2>[\s\w*,_]*)[)]|[\w ]*)""",
88 re.MULTILINE | re.VERBOSE)
89 pat = re.compile(r"""\s+""", re.MULTILINE)
92 m = typedef_pat.search(buf, pos)
95 if m.group('type') == 'enum':
98 if m.group('args2') != None:
99 args = pat.sub(' ', m.group('args2'))
101 current = '%s (* %s) (%s)' % (m.group('type'),
105 current = '%s %s' % (m.group('type'), m.group('args1'))
106 typedefs.append(current)
110 proto_pat = re.compile(r"""
111 (?P<ret>(-|\w|\&|\*)+\s*) # return type
112 \s+ # skip whitespace
113 (?P<func>\w+)\s*[(] # match the function name until the opening (
114 (?P<args>.*?)[)] # group the function arguments
115 """, re.IGNORECASE|re.VERBOSE)
116 arg_split_pat = re.compile("\s*,\s*")
119 def find_functions(buf):
121 buf = clean_func(buf)
122 buf = string.split(buf,'\n')
127 m = proto_pat.match(p)
131 func = m.group('func')
133 args = m.group('args')
134 args = arg_split_pat.split(args)
135 # for i in range(len(args)):
136 # spaces = string.count(args[i], ' ')
138 # args[i] = string.replace(args[i], ' ', '-', spaces - 1)
140 functions.append((func, ret, args))
144 def __init__(self, filename, enums, typedefs, functions):
145 if not (enums or typedefs or functions):
147 print 'cdef extern from "%s":' % filename
149 self.output_enums(enums)
150 self.output_typedefs(typedefs)
151 self.output_functions(functions)
156 def output_enums(self, enums):
158 print ' ctypedef enum %s:' % enum[0]
166 # print ' %s = 1 << %d' % (item, i)
169 def output_typedefs(self, typedefs):
170 for typedef in typedefs:
171 if typedef.find('va_list') != -1:
174 parts = typedef.split()
175 if parts[0] == 'struct':
176 if parts[-2] == parts[-1]:
178 print ' ctypedef %s' % ' '.join(parts)
180 print ' ctypedef %s' % typedef
182 def output_functions(self, functions):
183 for func, ret, args in functions:
187 str = ', '.join(args)
188 if str.find('...') != -1:
190 if str.find('va_list') != -1:
192 if str.strip() == 'void':
194 print ' %-20s %s (%s)' % (ret, func, str)
196 def do_buffer(name, buffer):
197 functions = find_functions(buffer)
198 typedefs = find_typedefs(buffer)
199 enums = find_enums(buffer)
201 Writer(name, enums, typedefs, functions)
203 def do_header(filename, name=None):
208 for line in open(filename).readlines():
213 print '# -- %s -- ' % filename
214 do_buffer(name, buffer)
216 filename = sys.argv[1]
218 if filename.endswith('.h'):
224 for flag in sys.argv[2:]:
225 cppflags = cppflags + " " + flag
229 for line in fd.readlines():
230 if line.startswith('#include'):
231 filename = line.split(' ')[1][1:-2]
232 command = "echo '%s'|cpp %s" % (line, cppflags)
233 sys.stderr.write('running %s' % (command))
234 output = commands.getoutput(command)
235 do_buffer(filename, output)