blob: 12ea8d7c48b7c5ad4ea98cad0b0cf278c6ebaa11 [file] [log] [blame]
Jeremy Hylton53d527a2002-08-05 18:29:45 +00001"""Rudimentary parser for C struct definitions."""
2
3import re
4
5PyObject_HEAD = "PyObject_HEAD"
6PyObject_VAR_HEAD = "PyObject_VAR_HEAD"
7
8rx_name = re.compile("} (\w+);")
9
10class 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
22def 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
Tim Peters182b5ac2004-07-18 06:16:08 +000038
Jeremy Hylton53d527a2002-08-05 18:29:45 +000039 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)