1"""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
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