Also track directly imported modules in a separate list
[free-sw/xcb/proto] / xcbgen / matcher.py
1 '''
2 XML parser.  One function for each top-level element in the schema.
3
4 Most functions just declare a new object and add it to the module.
5 For typedefs, eventcopies, xidtypes, and other aliases though,
6 we do not create a new type object, we just record the existing one under a new name.
7 '''
8
9 from os.path import join
10 from xml.etree.cElementTree import parse
11
12 from xcbgen.xtypes import *
13
14 def import_(node, module, namespace):
15     '''
16     For imports, we load the file, create a new namespace object,
17     execute recursively, then record the import (for header files, etc.)
18     '''
19     # To avoid circular import error
20     from xcbgen import state
21     module.import_level = module.import_level + 1
22     new_file = join(namespace.dir, '%s.xml' % node.text)
23     new_root = parse(new_file).getroot()
24     new_namespace = state.Namespace(new_file)
25     execute(module, new_namespace)
26     module.import_level = module.import_level - 1
27     if not module.has_import(node.text):
28         module.add_import(node.text, new_namespace)
29
30 def typedef(node, module, namespace):
31     id = node.get('newname')
32     name = namespace.prefix + (id,)
33     type = module.get_type(node.get('oldname'))
34     module.add_type(id, namespace.ns, name, type)
35
36 def xidtype(node, module, namespace):
37     id = node.get('name')
38     name = namespace.prefix + (id,)
39     type = module.get_type('CARD32')
40     module.add_type(id, namespace.ns, name, type)
41
42 def xidunion(node, module, namespace):
43     id = node.get('name')
44     name = namespace.prefix + (id,)
45     type = module.get_type('CARD32')
46     module.add_type(id, namespace.ns, name, type)
47
48 def enum(node, module, namespace):
49     id = node.get('name')
50     name = namespace.prefix + (id,)
51     type = Enum(name, node)
52     module.add_type(id, namespace.ns, name, type)
53
54 def struct(node, module, namespace):
55     id = node.get('name')
56     name = namespace.prefix + (id,)
57     type = Struct(name, node)
58     module.add_type(id, namespace.ns, name, type)
59
60 def union(node, module, namespace):
61     id = node.get('name')
62     name = namespace.prefix + (id,)
63     type = Union(name, node)
64     module.add_type(id, namespace.ns, name, type)
65
66 def request(node, module, namespace):
67     id = node.get('name')
68     name = namespace.prefix + (id,)
69     type = Request(name, node)
70     module.add_request(id, name, type)
71
72 def event(node, module, namespace):
73     id = node.get('name')
74     name = namespace.prefix + (id,)
75     event = Event(name, node)
76     event.add_opcode(node.get('number'), name, True)
77     module.add_event(id, name, event)
78
79 def eventcopy(node, module, namespace):
80     id = node.get('name')
81     name = namespace.prefix + (id,)
82     event = module.get_event(node.get('ref'))
83     event.add_opcode(node.get('number'), name, False)
84     module.add_event(id, name, event)
85
86 def error(node, module, namespace):
87     id = node.get('name')
88     name = namespace.prefix + (id,)
89     error = Error(name, node)
90     error.add_opcode(node.get('number'), name, True)
91     module.add_error(id, name, error)
92
93 def errorcopy(node, module, namespace):
94     id = node.get('name')
95     name = namespace.prefix + (id,)
96     error = module.get_error(node.get('ref'))
97     error.add_opcode(node.get('number'), name, False)
98     module.add_error(id, name, error)
99
100 funcs = {'import' : import_,
101          'typedef' : typedef,
102          'xidtype' : xidtype,
103          'xidunion' : xidunion,
104          'enum' : enum,
105          'struct' : struct,
106          'union' : union,
107          'request' : request,
108          'event' : event,
109          'eventcopy' : eventcopy,
110          'error' : error,
111          'errorcopy' : errorcopy}
112
113 def execute(module, namespace):
114     for elt in list(namespace.root):
115         funcs[elt.tag](elt, module, namespace)