153d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton"""Rudimentary parser for C struct definitions.""" 253d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton 353d527ad1828d484e336626ee59d7d5606b58499Jeremy Hyltonimport re 453d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton 553d527ad1828d484e336626ee59d7d5606b58499Jeremy HyltonPyObject_HEAD = "PyObject_HEAD" 653d527ad1828d484e336626ee59d7d5606b58499Jeremy HyltonPyObject_VAR_HEAD = "PyObject_VAR_HEAD" 753d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton 853d527ad1828d484e336626ee59d7d5606b58499Jeremy Hyltonrx_name = re.compile("} (\w+);") 953d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton 1053d527ad1828d484e336626ee59d7d5606b58499Jeremy Hyltonclass Struct: 1153d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton def __init__(self, name, head, members): 1253d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton self.name = name 1353d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton self.head = head 1453d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton self.members = members 1553d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton 1653d527ad1828d484e336626ee59d7d5606b58499Jeremy Hyltondef parse(s): 1753d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton """Parse a C struct definition. 1853d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton 1953d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton The parser is very restricted in what it will accept. 2053d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton """ 2153d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton 2253d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton lines = filter(None, s.split("\n")) # get non-empty lines 2353d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton assert lines[0].strip() == "typedef struct {" 2453d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton pyhead = lines[1].strip() 2553d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton assert (pyhead.startswith("PyObject") and 2653d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton pyhead.endswith("HEAD")) 2753d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton members = [] 2853d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton for line in lines[2:]: 2953d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton line = line.strip() 3053d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton if line.startswith("}"): 3153d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton break 32182b5aca27d376b08a2904bed42b751496f932f3Tim Peters 3353d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton assert line.endswith(";") 3453d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton line = line[:-1] 3553d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton words = line.split() 3653d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton name = words[-1] 3753d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton type = " ".join(words[:-1]) 3853d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton if name[0] == "*": 3953d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton name = name[1:] 4053d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton type += " *" 4153d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton members.append((name, type)) 4253d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton name = None 4353d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton mo = rx_name.search(line) 4453d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton assert mo is not None 4553d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton name = mo.group(1) 4653d527ad1828d484e336626ee59d7d5606b58499Jeremy Hylton return Struct(name, pyhead, members) 47