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