]> git.0d.be Git - empathy.git/blob - tools/c-constants-gen.py
don't pass a GError when first trying to start gnome-contacts
[empathy.git] / tools / c-constants-gen.py
1 #!/usr/bin/python
2
3 from sys import argv, stdout, stderr
4 import xml.dom.minidom
5
6 from libtpcodegen import file_set_contents, u
7 from libglibcodegen import NS_TP, get_docstring, \
8         get_descendant_text, get_by_path
9
10 class Generator(object):
11     def __init__(self, prefix, dom, output_base):
12         self.prefix = prefix + '_'
13         self.spec = get_by_path(dom, "spec")[0]
14
15         self.output_base = output_base
16         self.__header = []
17         self.__docs = []
18
19     def __call__(self):
20         self.do_header()
21         self.do_body()
22         self.do_footer()
23
24         file_set_contents(self.output_base + '.h', u('').join(self.__header).encode('utf-8'))
25         file_set_contents(self.output_base + '-gtk-doc.h', u('').join(self.__docs).encode('utf-8'))
26
27     def write(self, code):
28         self.__header.append(code)
29
30     def d(self, code):
31         self.__docs.append(code)
32
33     # Header
34     def do_header(self):
35         self.write('/* Generated from ')
36         self.write(get_descendant_text(get_by_path(self.spec, 'title')))
37         version = get_by_path(self.spec, "version")
38         if version:
39             self.write(', version ' + get_descendant_text(version))
40         self.write('\n\n')
41         for copyright in get_by_path(self.spec, 'copyright'):
42             self.write(get_descendant_text(copyright))
43             self.write('\n')
44         self.write(get_descendant_text(get_by_path(self.spec, 'license')))
45         self.write('\n')
46         self.write(get_descendant_text(get_by_path(self.spec, 'docstring')))
47         self.write("""
48  */
49
50 #ifdef __cplusplus
51 extern "C" {
52 #endif
53 \n""")
54
55     # Body
56     def do_body(self):
57         for elem in self.spec.getElementsByTagNameNS(NS_TP, '*'):
58             if elem.localName == 'flags':
59                 self.do_flags(elem)
60             elif elem.localName == 'enum':
61                 self.do_enum(elem)
62
63     def do_flags(self, flags):
64         name = flags.getAttribute('plural') or flags.getAttribute('name')
65         value_prefix = flags.getAttribute('singular') or \
66                        flags.getAttribute('value-prefix') or \
67                        flags.getAttribute('name')
68         self.d("""\
69 /**
70  * %s:
71 """ % (self.prefix + name).replace('_', ''))
72         for flag in get_by_path(flags, 'flag'):
73             self.do_gtkdoc(flag, value_prefix)
74         self.d(' *\n')
75         docstrings = get_by_path(flags, 'docstring')
76         if docstrings:
77             self.d("""\
78  * <![CDATA[%s]]>
79  *
80 """ % get_descendant_text(docstrings).replace('\n', ' '))
81         self.d("""\
82  * Bitfield/set of flags generated from the Telepathy specification.
83  */
84 """)
85
86         self.write("typedef enum /*< flags >*/ {\n")
87
88         for flag in get_by_path(flags, 'flag'):
89             self.do_val(flag, value_prefix)
90         self.write("""\
91 } %s;
92
93 """ % (self.prefix + name).replace('_', ''))
94
95     def do_enum(self, enum):
96         name = enum.getAttribute('singular') or enum.getAttribute('name')
97         value_prefix = enum.getAttribute('singular') or \
98                        enum.getAttribute('value-prefix') or \
99                        enum.getAttribute('name')
100         name_plural = enum.getAttribute('plural') or \
101                       enum.getAttribute('name') + 's'
102         self.d("""\
103 /**
104  * %s:
105 """ % (self.prefix + name).replace('_', ''))
106         vals = get_by_path(enum, 'enumvalue')
107         for val in vals:
108             self.do_gtkdoc(val, value_prefix)
109         self.d(' *\n')
110         docstrings = get_by_path(enum, 'docstring')
111         if docstrings:
112             self.d("""\
113  * <![CDATA[%s]]>
114  *
115 """ % get_descendant_text(docstrings).replace('\n', ' '))
116         self.d("""\
117  * Bitfield/set of flags generated from the Telepathy specification.
118  */
119 """)
120
121         self.write("typedef enum {\n")
122
123         for val in vals:
124             self.do_val(val, value_prefix)
125         self.write("} %s;\n" % (self.prefix + name).replace('_', ''))
126
127         self.d("""\
128 /**
129  * %(upper-prefix)sNUM_%(upper-plural)s:
130  *
131  * 1 higher than the highest valid value of #%(mixed-name)s.
132  */
133
134 /**
135  * NUM_%(upper-prefix)s%(upper-plural)s: (skip)
136  *
137  * 1 higher than the highest valid value of #%(mixed-name)s.
138  * In new code, use %(upper-prefix)sNUM_%(upper-plural)s instead.
139  */
140 """ % {'mixed-name' : (self.prefix + name).replace('_', ''),
141        'upper-prefix' : self.prefix.upper(),
142        'upper-plural' : name_plural.upper(),
143        'last-val' : vals[-1].getAttribute('value')})
144
145         self.write("""\
146 #define %(upper-prefix)sNUM_%(upper-plural)s (%(last-val)s+1)
147 #define NUM_%(upper-prefix)s%(upper-plural)s %(upper-prefix)sNUM_%(upper-plural)s
148
149 """ % {'mixed-name' : (self.prefix + name).replace('_', ''),
150        'upper-prefix' : self.prefix.upper(),
151        'upper-plural' : name_plural.upper(),
152        'last-val' : vals[-1].getAttribute('value')})
153
154     def do_val(self, val, value_prefix):
155         name = val.getAttribute('name')
156         suffix = val.getAttribute('suffix')
157         use_name = (self.prefix + value_prefix + '_' + \
158                 (suffix or name)).upper()
159         assert not (name and suffix) or name == suffix, \
160                 'Flag/enumvalue name %s != suffix %s' % (name, suffix)
161         self.write('    %s = %s,\n' % (use_name, val.getAttribute('value')))
162
163     def do_gtkdoc(self, node, value_prefix):
164         self.d(' * @')
165         self.d((self.prefix + value_prefix + '_' +
166             node.getAttribute('suffix')).upper())
167         self.d(': <![CDATA[')
168         docstring = get_by_path(node, 'docstring')
169         self.d(get_descendant_text(docstring).replace('\n', ' '))
170         self.d(']]>\n')
171
172     # Footer
173     def do_footer(self):
174         self.write("""
175 #ifdef __cplusplus
176 }
177 #endif
178 """)
179
180 if __name__ == '__main__':
181     argv = argv[1:]
182     Generator(argv[0], xml.dom.minidom.parse(argv[1]), argv[2])()