blob: 8fc2aec27dc806d16aec530c0c8261e82b72c6a8 [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
Collin Wintera817e582007-08-22 23:05:06 +000020 raise ValueError("no member named %s" % name)
Jeremy Hylton53d527a2002-08-05 18:29:45 +000021
22def parse(s):
23 """Parse a C struct definition.
24
25 The parser is very restricted in what it will accept.
26 """
27
Georg Brandlbf82e372008-05-16 17:02:34 +000028 lines = [_f for _f in s.split("\n") if _f] # get non-empty lines
Jeremy Hylton53d527a2002-08-05 18:29:45 +000029 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)