Changeset View
Changeset View
Standalone View
Standalone View
tools/glib-interfaces-gen.py
1 | #!/usr/bin/python | 1 | #!/usr/bin/python | ||
---|---|---|---|---|---|
2 | 2 | | |||
3 | from sys import argv, stdout, stderr | 3 | from sys import argv, stdout, stderr | ||
4 | import xml.dom.minidom | 4 | import xml.dom.minidom | ||
5 | 5 | | |||
6 | from libtpcodegen import file_set_contents, u | ||||
6 | from libglibcodegen import NS_TP, get_docstring, \ | 7 | from libglibcodegen import NS_TP, get_docstring, \ | ||
7 | get_descendant_text, get_by_path | 8 | get_descendant_text, get_by_path | ||
8 | 9 | | |||
9 | class Generator(object): | 10 | class Generator(object): | ||
10 | def __init__(self, prefix, implfile, declfile, dom): | 11 | def __init__(self, prefix, implfile, declfile, dom): | ||
11 | self.prefix = prefix + '_' | 12 | self.prefix = prefix + '_' | ||
12 | self.impls = open(implfile, 'w') | 13 | | ||
13 | self.decls = open(declfile, 'w') | 14 | assert declfile.endswith('.h') | ||
15 | docfile = declfile[:-2] + '-gtk-doc.h' | ||||
16 | | ||||
17 | self.implfile = implfile | ||||
18 | self.declfile = declfile | ||||
19 | self.docfile = docfile | ||||
20 | | ||||
21 | self.impls = [] | ||||
22 | self.decls = [] | ||||
23 | self.docs = [] | ||||
14 | self.spec = get_by_path(dom, "spec")[0] | 24 | self.spec = get_by_path(dom, "spec")[0] | ||
15 | 25 | | |||
16 | def h(self, code): | 26 | def h(self, code): | ||
17 | self.decls.write(code.encode('utf-8')) | 27 | self.decls.append(code) | ||
18 | 28 | | |||
19 | def c(self, code): | 29 | def c(self, code): | ||
20 | self.impls.write(code.encode('utf-8')) | 30 | self.impls.append(code) | ||
31 | | ||||
32 | def d(self, code): | ||||
33 | self.docs.append(code) | ||||
21 | 34 | | |||
22 | def __call__(self): | 35 | def __call__(self): | ||
23 | for f in self.h, self.c: | 36 | for f in self.h, self.c: | ||
24 | self.do_header(f) | 37 | self.do_header(f) | ||
25 | self.do_body() | 38 | self.do_body() | ||
26 | 39 | | |||
40 | file_set_contents(self.implfile, u('').join(self.impls).encode('utf-8')) | ||||
41 | file_set_contents(self.declfile, u('').join(self.decls).encode('utf-8')) | ||||
42 | file_set_contents(self.docfile, u('').join(self.docs).encode('utf-8')) | ||||
43 | | ||||
27 | # Header | 44 | # Header | ||
28 | def do_header(self, f): | 45 | def do_header(self, f): | ||
29 | f('/* Generated from: ') | 46 | f('/* Generated from: ') | ||
30 | f(get_descendant_text(get_by_path(self.spec, 'title'))) | 47 | f(get_descendant_text(get_by_path(self.spec, 'title'))) | ||
31 | version = get_by_path(self.spec, "version") | 48 | version = get_by_path(self.spec, "version") | ||
32 | if version: | 49 | if version: | ||
33 | f(' version ' + get_descendant_text(version)) | 50 | f(' version ' + get_descendant_text(version)) | ||
34 | f('\n\n') | 51 | f('\n\n') | ||
35 | for copyright in get_by_path(self.spec, 'copyright'): | 52 | for copyright in get_by_path(self.spec, 'copyright'): | ||
36 | f(get_descendant_text(copyright)) | 53 | f(get_descendant_text(copyright)) | ||
37 | f('\n') | 54 | f('\n') | ||
38 | f('\n') | 55 | f('\n') | ||
39 | f(get_descendant_text(get_by_path(self.spec, 'license'))) | 56 | f(get_descendant_text(get_by_path(self.spec, 'license'))) | ||
40 | f(get_descendant_text(get_by_path(self.spec, 'docstring'))) | 57 | f(get_descendant_text(get_by_path(self.spec, 'docstring'))) | ||
41 | f(""" | 58 | f(""" | ||
42 | */ | 59 | */ | ||
43 | 60 | | |||
61 | #include <glib.h> | ||||
44 | """) | 62 | """) | ||
45 | 63 | | |||
46 | # Body | 64 | # Body | ||
47 | def do_body(self): | 65 | def do_body(self): | ||
48 | for iface in self.spec.getElementsByTagName('interface'): | 66 | for iface in self.spec.getElementsByTagName('interface'): | ||
49 | self.do_iface(iface) | 67 | self.do_iface(iface) | ||
50 | 68 | | |||
51 | def do_iface(self, iface): | 69 | def do_iface(self, iface): | ||
52 | parent_name = get_by_path(iface, '../@name') | 70 | parent_name = get_by_path(iface, '../@name') | ||
53 | self.h("""\ | 71 | self.d("""\ | ||
54 | /** | 72 | /** | ||
55 | * %(IFACE_DEFINE)s: | 73 | * %(IFACE_DEFINE)s: | ||
56 | * | 74 | * | ||
57 | * The interface name "%(name)s" | 75 | * The interface name "%(name)s" | ||
58 | */ | 76 | */ | ||
77 | """ % {'IFACE_DEFINE' : (self.prefix + 'IFACE_' + \ | ||||
78 | parent_name).upper().replace('/', ''), | ||||
79 | 'name' : iface.getAttribute('name')}) | ||||
80 | | ||||
81 | self.h(""" | ||||
59 | #define %(IFACE_DEFINE)s \\ | 82 | #define %(IFACE_DEFINE)s \\ | ||
60 | "%(name)s" | 83 | "%(name)s" | ||
61 | """ % {'IFACE_DEFINE' : (self.prefix + 'IFACE_' + \ | 84 | """ % {'IFACE_DEFINE' : (self.prefix + 'IFACE_' + \ | ||
62 | parent_name).upper().replace('/', ''), | 85 | parent_name).upper().replace('/', ''), | ||
63 | 'name' : iface.getAttribute('name')}) | 86 | 'name' : iface.getAttribute('name')}) | ||
64 | 87 | | |||
65 | self.h(""" | 88 | self.d(""" | ||
66 | /** | 89 | /** | ||
67 | * %(IFACE_QUARK_DEFINE)s: | 90 | * %(IFACE_QUARK_DEFINE)s: | ||
68 | * | 91 | * | ||
69 | * Expands to a call to a function that returns a quark for the interface \ | 92 | * Expands to a call to a function that returns a quark for the interface \ | ||
70 | name "%(name)s" | 93 | name "%(name)s" | ||
71 | */ | 94 | */ | ||
95 | """ % {'IFACE_QUARK_DEFINE' : (self.prefix + 'IFACE_QUARK_' + \ | ||||
96 | parent_name).upper().replace('/', ''), | ||||
97 | 'iface_quark_func' : (self.prefix + 'iface_quark_' + \ | ||||
98 | parent_name).lower().replace('/', ''), | ||||
99 | 'name' : iface.getAttribute('name')}) | ||||
100 | | ||||
101 | self.h(""" | ||||
72 | #define %(IFACE_QUARK_DEFINE)s \\ | 102 | #define %(IFACE_QUARK_DEFINE)s \\ | ||
73 | (%(iface_quark_func)s ()) | 103 | (%(iface_quark_func)s ()) | ||
74 | 104 | | |||
75 | GQuark %(iface_quark_func)s (void); | 105 | GQuark %(iface_quark_func)s (void); | ||
76 | 106 | | |||
77 | """ % {'IFACE_QUARK_DEFINE' : (self.prefix + 'IFACE_QUARK_' + \ | 107 | """ % {'IFACE_QUARK_DEFINE' : (self.prefix + 'IFACE_QUARK_' + \ | ||
78 | parent_name).upper().replace('/', ''), | 108 | parent_name).upper().replace('/', ''), | ||
79 | 'iface_quark_func' : (self.prefix + 'iface_quark_' + \ | 109 | 'iface_quark_func' : (self.prefix + 'iface_quark_' + \ | ||
Show All 14 Lines | 116 | { | |||
94 | return quark; | 124 | return quark; | ||
95 | } | 125 | } | ||
96 | 126 | | |||
97 | """ % {'iface_quark_func' : (self.prefix + 'iface_quark_' + \ | 127 | """ % {'iface_quark_func' : (self.prefix + 'iface_quark_' + \ | ||
98 | parent_name).lower().replace('/', ''), | 128 | parent_name).lower().replace('/', ''), | ||
99 | 'name' : iface.getAttribute('name')}) | 129 | 'name' : iface.getAttribute('name')}) | ||
100 | 130 | | |||
101 | for prop in iface.getElementsByTagNameNS(None, 'property'): | 131 | for prop in iface.getElementsByTagNameNS(None, 'property'): | ||
102 | self.decls.write(""" | 132 | self.d(""" | ||
103 | /** | 133 | /** | ||
104 | * %(IFACE_PREFIX)s_%(PROP_UC)s: | 134 | * %(IFACE_PREFIX)s_%(PROP_UC)s: | ||
105 | * | 135 | * | ||
106 | * The fully-qualified property name "%(name)s.%(prop)s" | 136 | * The fully-qualified property name "%(name)s.%(prop)s" | ||
107 | */ | 137 | */ | ||
138 | """ % {'IFACE_PREFIX' : (self.prefix + 'PROP_' + \ | ||||
139 | parent_name).upper().replace('/', ''), | ||||
140 | 'PROP_UC': prop.getAttributeNS(NS_TP, "name-for-bindings").upper(), | ||||
141 | 'name' : iface.getAttribute('name'), | ||||
142 | 'prop' : prop.getAttribute('name'), | ||||
143 | }) | ||||
144 | | ||||
145 | self.h(""" | ||||
108 | #define %(IFACE_PREFIX)s_%(PROP_UC)s \\ | 146 | #define %(IFACE_PREFIX)s_%(PROP_UC)s \\ | ||
109 | "%(name)s.%(prop)s" | 147 | "%(name)s.%(prop)s" | ||
110 | """ % {'IFACE_PREFIX' : (self.prefix + 'PROP_' + \ | 148 | """ % {'IFACE_PREFIX' : (self.prefix + 'PROP_' + \ | ||
111 | parent_name).upper().replace('/', ''), | 149 | parent_name).upper().replace('/', ''), | ||
112 | 'PROP_UC': prop.getAttributeNS(NS_TP, "name-for-bindings").upper(), | 150 | 'PROP_UC': prop.getAttributeNS(NS_TP, "name-for-bindings").upper(), | ||
113 | 'name' : iface.getAttribute('name'), | 151 | 'name' : iface.getAttribute('name'), | ||
114 | 'prop' : prop.getAttribute('name'), | 152 | 'prop' : prop.getAttribute('name'), | ||
115 | }) | 153 | }) | ||
116 | 154 | | |||
155 | | ||||
156 | for prop in iface.getElementsByTagNameNS(NS_TP, 'contact-attribute'): | ||||
157 | self.d(""" | ||||
158 | /** | ||||
159 | * %(TOKEN_PREFIX)s_%(TOKEN_UC)s: | ||||
160 | * | ||||
161 | * The fully-qualified contact attribute token name "%(name)s/%(prop)s" | ||||
162 | */ | ||||
163 | """ % {'TOKEN_PREFIX' : (self.prefix + 'TOKEN_' + \ | ||||
164 | parent_name).upper().replace('/', ''), | ||||
165 | 'TOKEN_UC': prop.getAttributeNS(None, "name").upper().replace("-", "_").replace(".", "_"), | ||||
166 | 'name' : iface.getAttribute('name'), | ||||
167 | 'prop' : prop.getAttribute('name'), | ||||
168 | }) | ||||
169 | | ||||
170 | self.h(""" | ||||
171 | #define %(TOKEN_PREFIX)s_%(TOKEN_UC)s \\ | ||||
172 | "%(name)s/%(prop)s" | ||||
173 | """ % {'TOKEN_PREFIX' : (self.prefix + 'TOKEN_' + \ | ||||
174 | parent_name).upper().replace('/', ''), | ||||
175 | 'TOKEN_UC': prop.getAttributeNS(None, "name").upper().replace("-", "_").replace(".", "_"), | ||||
176 | 'name' : iface.getAttribute('name'), | ||||
177 | 'prop' : prop.getAttribute('name'), | ||||
178 | }) | ||||
179 | | ||||
180 | for prop in iface.getElementsByTagNameNS(NS_TP, 'hct'): | ||||
181 | if (prop.getAttribute('is-family') != "yes"): | ||||
182 | self.d(""" | ||||
183 | /** | ||||
184 | * %(TOKEN_PREFIX)s_%(TOKEN_UC)s: | ||||
185 | * | ||||
186 | * The fully-qualified capability token name "%(name)s/%(prop)s" | ||||
187 | */ | ||||
188 | """ % {'TOKEN_PREFIX' : (self.prefix + 'TOKEN_' + \ | ||||
189 | parent_name).upper().replace('/', ''), | ||||
190 | 'TOKEN_UC': prop.getAttributeNS(None, "name").upper().replace("-", "_").replace(".", "_"), | ||||
191 | 'name' : iface.getAttribute('name'), | ||||
192 | 'prop' : prop.getAttribute('name'), | ||||
193 | }) | ||||
194 | | ||||
195 | self.h(""" | ||||
196 | #define %(TOKEN_PREFIX)s_%(TOKEN_UC)s \\ | ||||
197 | "%(name)s/%(prop)s" | ||||
198 | """ % {'TOKEN_PREFIX' : (self.prefix + 'TOKEN_' + \ | ||||
199 | parent_name).upper().replace('/', ''), | ||||
200 | 'TOKEN_UC': prop.getAttributeNS(None, "name").upper().replace("-", "_").replace(".", "_"), | ||||
201 | 'name' : iface.getAttribute('name'), | ||||
202 | 'prop' : prop.getAttribute('name'), | ||||
203 | }) | ||||
204 | | ||||
117 | if __name__ == '__main__': | 205 | if __name__ == '__main__': | ||
118 | argv = argv[1:] | 206 | argv = argv[1:] | ||
119 | Generator(argv[0], argv[1], argv[2], xml.dom.minidom.parse(argv[3]))() | 207 | Generator(argv[0], argv[1], argv[2], xml.dom.minidom.parse(argv[3]))() |