Add Python parser language-independent parts.
[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 import state
13 from types import *
14
15 def import_(node, module, namespace):
16     '''
17     For imports, we load the file, create a new namespace object,
18     execute recursively, then record the import (for header files, etc.)
19     '''
20     new_file = join(namespace.dir, '%s.xml' % node.text)
21     new_root = parse(new_file).getroot()
22     new_namespace = state.Namespace(new_file)
23     execute(module, new_namespace)
24     if not module.has_import(node.text):
25         module.add_import(node.text, new_namespace)
26
27 def typedef(node, module, namespace):
28     id = node.get('newname')
29     name = namespace.prefix + (id,)
30     type = module.get_type(node.get('oldname'))
31     module.add_type(id, namespace.ns, name, type)
32
33 def xidtype(node, module, namespace):
34     id = node.get('name')
35     name = namespace.prefix + (id,)
36     type = module.get_type('CARD32')
37     module.add_type(id, namespace.ns, name, type)
38
39 def xidunion(node, module, namespace):
40     id = node.get('name')
41     name = namespace.prefix + (id,)
42     type = module.get_type('CARD32')
43     module.add_type(id, namespace.ns, name, type)
44
45 def enum(node, module, namespace):
46     id = node.get('name')
47     name = namespace.prefix + (id,)
48     type = Enum(name, node)
49     module.add_type(id, namespace.ns, name, type)
50
51 def struct(node, module, namespace):
52     id = node.get('name')
53     name = namespace.prefix + (id,)
54     type = Struct(name, node)
55     module.add_type(id, namespace.ns, name, type)
56
57 def union(node, module, namespace):
58     id = node.get('name')
59     name = namespace.prefix + (id,)
60     type = Union(name, node)
61     module.add_type(id, namespace.ns, name, type)
62
63 def request(node, module, namespace):
64     id = node.get('name')
65     name = namespace.prefix + (id,)
66     type = Request(name, node)
67     module.add_request(id, name, type)
68
69 def event(node, module, namespace):
70     id = node.get('name')
71     name = namespace.prefix + (id,)
72     event = Event(name, node)
73     event.add_opcode(node.get('number'), name, True)
74     module.add_event(id, name, event)
75
76 def eventcopy(node, module, namespace):
77     id = node.get('name')
78     name = namespace.prefix + (id,)
79     event = module.get_event(node.get('ref'))
80     event.add_opcode(node.get('number'), name, False)
81     module.add_event(id, name, event)
82
83 def error(node, module, namespace):
84     id = node.get('name')
85     name = namespace.prefix + (id,)
86     error = Error(name, node)
87     error.add_opcode(node.get('number'), name, True)
88     module.add_error(id, name, error)
89
90 def errorcopy(node, module, namespace):
91     id = node.get('name')
92     name = namespace.prefix + (id,)
93     error = module.get_error(node.get('ref'))
94     error.add_opcode(node.get('number'), name, False)
95     module.add_error(id, name, error)
96
97 funcs = {'import' : import_,
98          'typedef' : typedef,
99          'xidtype' : xidtype,
100          'xidunion' : xidunion,
101          'enum' : enum,
102          'struct' : struct,
103          'union' : union,
104          'request' : request,
105          'event' : event,
106          'eventcopy' : eventcopy,
107          'error' : error,
108          'errorcopy' : errorcopy}
109
110 def execute(module, namespace):
111     for elt in list(namespace.root):
112         funcs[elt.tag](elt, module, namespace)