Home | History | Annotate | Download | only in framer
      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