1 """Rudimentary parser for C struct definitions.""" 2 3 import re 4 5 PyObject_HEAD = "PyObject_HEAD" 6 PyObject_VAR_HEAD = "PyObject_VAR_HEAD" 7 8 rx_name = re.compile("} (\w+);") 9 10 class Struct: 11 def __init__(self, name, head, members): 12 self.name = name 13 self.head = head 14 self.members = members 15 16 def get_type(self, name): 17 for _name, type in self.members: 18 if name == _name: 19 return type 20 raise ValueError, "no member named %s" % name 21 22 def parse(s): 23 """Parse a C struct definition. 24 25 The parser is very restricted in what it will accept. 26 """ 27 28 lines = filter(None, s.split("\n")) # get non-empty lines 29 assert lines[0].strip() == "typedef struct {" 30 pyhead = lines[1].strip() 31 assert (pyhead.startswith("PyObject") and 32 pyhead.endswith("HEAD")) 33 members = [] 34 for line in lines[2:]: 35 line = line.strip() 36 if line.startswith("}"): 37 break 38 39 assert line.endswith(";") 40 line = line[:-1] 41 words = line.split() 42 name = words[-1] 43 type = " ".join(words[:-1]) 44 if name[0] == "*": 45 name = name[1:] 46 type += " *" 47 members.append((name, type)) 48 name = None 49 mo = rx_name.search(line) 50 assert mo is not None 51 name = mo.group(1) 52 return Struct(name, pyhead, members) 53