Avoid name collisions between xidtype and enum.
[free-sw/xcb/libxcb] / src / c_client.py
1 #!/usr/bin/env python
2 from xml.etree.cElementTree import *
3 from os.path import basename
4 import getopt
5 import sys
6 import re
7
8 # Jump to the bottom of this file for the main routine
9
10 # Some hacks to make the API more readable, and to keep backwards compability
11 _cname_re = re.compile('([A-Z0-9][a-z]+|[A-Z0-9]+(?![a-z])|[a-z]+)')
12 _cname_special_cases = {'DECnet':'decnet'}
13
14 _extension_special_cases = ['XPrint', 'XCMisc', 'BigRequests']
15
16 _cplusplus_annoyances = {'class' : '_class',
17                          'new'   : '_new',
18                          'delete': '_delete'}
19
20 _hlines = []
21 _hlevel = 0
22 _clines = []
23 _clevel = 0
24 _ns = None
25
26 def _h(fmt, *args):
27     '''
28     Writes the given line to the header file.
29     '''
30     _hlines[_hlevel].append(fmt % args)
31     
32 def _c(fmt, *args):
33     '''
34     Writes the given line to the source file.
35     '''
36     _clines[_clevel].append(fmt % args)
37     
38 def _hc(fmt, *args):
39     '''
40     Writes the given line to both the header and source files.
41     '''
42     _h(fmt, *args)
43     _c(fmt, *args)
44
45 # XXX See if this level thing is really necessary.
46 def _h_setlevel(idx):
47     '''
48     Changes the array that header lines are written to.
49     Supports writing different sections of the header file.
50     '''
51     global _hlevel
52     while len(_hlines) <= idx:
53         _hlines.append([])
54     _hlevel = idx
55     
56 def _c_setlevel(idx):
57     '''
58     Changes the array that source lines are written to.
59     Supports writing to different sections of the source file.
60     '''
61     global _clevel
62     while len(_clines) <= idx:
63         _clines.append([])
64     _clevel = idx
65     
66 def _n_item(str):
67     '''
68     Does C-name conversion on a single string fragment.
69     Uses a regexp with some hard-coded special cases.
70     '''
71     if str in _cname_special_cases:
72         return _cname_special_cases[str]
73     else:
74         split = _cname_re.finditer(str)
75         name_parts = [match.group(0) for match in split]
76         return '_'.join(name_parts)
77     
78 def _cpp(str):
79     '''
80     Checks for certain C++ reserved words and fixes them.
81     '''
82     if str in _cplusplus_annoyances:
83         return _cplusplus_annoyances[str]
84     else:
85         return str
86
87 def _ext(str):
88     '''
89     Does C-name conversion on an extension name.
90     Has some additional special cases on top of _n_item.
91     '''
92     if str in _extension_special_cases:
93         return _n_item(str).lower()
94     else:
95         return str.lower()
96     
97 def _n(list):
98     '''
99     Does C-name conversion on a tuple of strings.
100     Different behavior depending on length of tuple, extension/not extension, etc.
101     Basically C-name converts the individual pieces, then joins with underscores.
102     '''
103     if len(list) == 1:
104         parts = list
105     elif len(list) == 2:
106         parts = [list[0], _n_item(list[1])]
107     elif _ns.is_ext:
108         parts = [list[0], _ext(list[1])] + [_n_item(i) for i in list[2:]]
109     else:
110         parts = [list[0]] + [_n_item(i) for i in list[1:]]
111     return '_'.join(parts).lower()
112
113 def _t(list):
114     '''
115     Does C-name conversion on a tuple of strings representing a type.
116     Same as _n but adds a "_t" on the end.
117     '''
118     if len(list) == 1:
119         parts = list
120     elif len(list) == 2:
121         parts = [list[0], _n_item(list[1]), 't']
122     elif _ns.is_ext:
123         parts = [list[0], _ext(list[1])] + [_n_item(i) for i in list[2:]] + ['t']
124     else:
125         parts = [list[0]] + [_n_item(i) for i in list[1:]] + ['t']
126     return '_'.join(parts).lower()
127         
128
129 def c_open(self):
130     '''
131     Exported function that handles module open.
132     Opens the files and writes out the auto-generated comment, header file includes, etc.
133     '''
134     global _ns
135     _ns = self.namespace
136     _ns.c_ext_global_name = _n(_ns.prefix + ('id',))
137
138     # Build the type-name collision avoidance table used by c_enum
139     build_collision_table()
140
141     _h_setlevel(0)
142     _c_setlevel(0)
143
144     _hc('/*')
145     _hc(' * This file generated automatically from %s by c_client.py.', _ns.file)
146     _hc(' * Edit at your peril.')
147     _hc(' */')
148     _hc('')
149
150     _h('/**')
151     _h(' * @defgroup XCB_%s_API XCB %s API', _ns.ext_name, _ns.ext_name)
152     _h(' * @brief %s XCB Protocol Implementation.', _ns.ext_name)
153     _h(' * @{')
154     _h(' **/')
155     _h('')
156     _h('#ifndef __%s_H', _ns.header.upper())
157     _h('#define __%s_H', _ns.header.upper())
158     _h('')
159     _h('#include "xcb.h"')
160
161     _c('#include <string.h>')
162     _c('#include <assert.h>')
163     _c('#include "xcbext.h"')
164     _c('#include "%s.h"', _ns.header)
165         
166     if _ns.is_ext:
167         for (n, h) in self.imports:
168             _hc('#include "%s.h"', h)
169
170     _h('')
171     _h('#ifdef __cplusplus')
172     _h('extern "C" {')
173     _h('#endif')
174
175     if _ns.is_ext:
176         _h('')
177         _h('#define XCB_%s_MAJOR_VERSION %s', _ns.ext_name.upper(), _ns.major_version)
178         _h('#define XCB_%s_MINOR_VERSION %s', _ns.ext_name.upper(), _ns.minor_version)
179         _h('  ') #XXX
180         _h('extern xcb_extension_t %s;', _ns.c_ext_global_name)
181
182         _c('')
183         _c('xcb_extension_t %s = { "%s", 0 };', _ns.c_ext_global_name, _ns.ext_xname)
184
185 def c_close(self):
186     '''
187     Exported function that handles module close.
188     Writes out all the stored content lines, then closes the files.
189     '''
190     _h_setlevel(2)
191     _c_setlevel(2)
192     _hc('')
193
194     _h('')
195     _h('#ifdef __cplusplus')
196     _h('}')
197     _h('#endif')
198
199     _h('')
200     _h('#endif')
201     _h('')
202     _h('/**')
203     _h(' * @}')
204     _h(' */')
205
206     # Write header file
207     hfile = open('%s.h' % _ns.header, 'w')
208     for list in _hlines:
209         for line in list:
210             hfile.write(line)
211             hfile.write('\n')
212     hfile.close()
213
214     # Write source file
215     cfile = open('%s.c' % _ns.header, 'w')
216     for list in _clines:
217         for line in list:
218             cfile.write(line)
219             cfile.write('\n')
220     cfile.close()
221
222 def build_collision_table():
223     global namecount
224     namecount = {}
225
226     for v in module.types.values():
227         name = _t(v[0])
228         namecount[name] = (namecount.get(name) or 0) + 1
229
230 def c_enum(self, name):
231     '''
232     Exported function that handles enum declarations.
233     '''
234
235     tname = _t(name)
236     if namecount[tname] > 1:
237         tname = _t(name + ('enum',))
238
239     _h_setlevel(0)
240     _h('')
241     _h('typedef enum %s {', tname)
242
243     count = len(self.values)
244
245     for (enam, eval) in self.values:
246         count = count - 1
247         equals = ' = ' if eval != '' else ''
248         comma = ',' if count > 0 else ''
249         _h('    %s%s%s%s', _n(name + (enam,)).upper(), equals, eval, comma)
250
251     _h('} %s;', tname)
252
253 def _c_type_setup(self, name, postfix):
254     '''
255     Sets up all the C-related state by adding additional data fields to
256     all Field and Type objects.  Here is where we figure out most of our
257     variable and function names.
258
259     Recurses into child fields and list member types.
260     '''
261     # Do all the various names in advance
262     self.c_type = _t(name + postfix)
263     self.c_wiretype = 'char' if self.c_type == 'void' else self.c_type
264
265     self.c_iterator_type = _t(name + ('iterator',))
266     self.c_next_name = _n(name + ('next',))
267     self.c_end_name = _n(name + ('end',))
268
269     self.c_request_name = _n(name)
270     self.c_checked_name = _n(name + ('checked',))
271     self.c_unchecked_name = _n(name + ('unchecked',))
272     self.c_reply_name = _n(name + ('reply',))
273     self.c_reply_type = _t(name + ('reply',))
274     self.c_cookie_type = _t(name + ('cookie',))
275
276     if self.is_container:
277
278         self.c_container = 'union' if self.is_union else 'struct'
279         prev_varsized_field = None
280         prev_varsized_offset = 0
281         first_field_after_varsized = None
282
283         for field in self.fields:
284             _c_type_setup(field.type, field.field_type, ())
285             if field.type.is_list:
286                 _c_type_setup(field.type.member, field.field_type, ())
287
288             field.c_field_type = _t(field.field_type)
289             field.c_field_const_type = ('' if field.type.nmemb == 1 else 'const ') + field.c_field_type
290             field.c_field_name = _cpp(field.field_name)
291             field.c_subscript = '[%d]' % field.type.nmemb if (field.type.nmemb > 1) else ''
292             field.c_pointer = ' ' if field.type.nmemb == 1 else '*'
293
294             field.c_iterator_type = _t(field.field_type + ('iterator',))      # xcb_fieldtype_iterator_t
295             field.c_iterator_name = _n(name + (field.field_name, 'iterator')) # xcb_container_field_iterator
296             field.c_accessor_name = _n(name + (field.field_name,))            # xcb_container_field
297             field.c_length_name = _n(name + (field.field_name, 'length'))     # xcb_container_field_length
298             field.c_end_name = _n(name + (field.field_name, 'end'))           # xcb_container_field_end
299
300             field.prev_varsized_field = prev_varsized_field
301             field.prev_varsized_offset = prev_varsized_offset
302
303             if prev_varsized_offset == 0:
304                 first_field_after_varsized = field
305             field.first_field_after_varsized = first_field_after_varsized
306
307             if field.type.fixed_size():
308                 prev_varsized_offset += field.type.size
309             else:
310                 self.last_varsized_field = field
311                 prev_varsized_field = field
312                 prev_varsized_offset = 0
313
314 def _c_iterator_get_end(field, accum):
315     '''
316     Figures out what C code is needed to find the end of a variable-length structure field.
317     For nested structures, recurses into its last variable-sized field.
318     For lists, calls the end function
319     '''
320     if field.type.is_container:
321         accum = field.c_accessor_name + '(' + accum + ')'
322         # XXX there could be fixed-length fields at the end
323         return _c_iterator_get_end(field.type.last_varsized_field, accum)
324     if field.type.is_list:
325         # XXX we can always use the first way
326         if field.type.member.is_simple:
327             return field.c_end_name + '(' + accum + ')'
328         else:
329             return field.type.member.c_end_name + '(' + field.c_iterator_name + '(' + accum + '))'
330
331 def _c_iterator(self, name):
332     '''
333     Declares the iterator structure and next/end functions for a given type.
334     '''
335     _h_setlevel(0)
336     _h('')
337     _h('/**')
338     _h(' * @brief %s', self.c_iterator_type)
339     _h(' **/')
340     _h('typedef struct %s {', self.c_iterator_type)
341     _h('    %s *data; /**<  */', self.c_type)
342     _h('    int%s rem; /**<  */', ' ' * (len(self.c_type) - 2))
343     _h('    int%s index; /**<  */', ' ' * (len(self.c_type) - 2))
344     _h('} %s;', self.c_iterator_type)
345
346     _h_setlevel(1)
347     _c_setlevel(1)
348     _h('')
349     _h('/**')
350     _h(' * Get the next element of the iterator')
351     _h(' * @param i Pointer to a %s', self.c_iterator_type)
352     _h(' *')
353     _h(' * Get the next element in the iterator. The member rem is')
354     _h(' * decreased by one. The member data points to the next')
355     _h(' * element. The member index is increased by sizeof(%s)', self.c_type)
356     _h(' */')
357     _c('')
358     _hc('')
359     _hc('/*****************************************************************************')
360     _hc(' **')
361     _hc(' ** void %s', self.c_next_name)
362     _hc(' ** ')
363     _hc(' ** @param %s *i', self.c_iterator_type)
364     _hc(' ** @returns void')
365     _hc(' **')
366     _hc(' *****************************************************************************/')
367     _hc(' ')
368     _hc('void')
369     _h('%s (%s *i  /**< */);', self.c_next_name, self.c_iterator_type)
370     _c('%s (%s *i  /**< */)', self.c_next_name, self.c_iterator_type)
371     _c('{')
372
373     if not self.fixed_size():
374         _c('    %s *R = i->data;', self.c_type)
375         _c('    xcb_generic_iterator_t child = %s;', _c_iterator_get_end(self.last_varsized_field, 'R'))
376         _c('    --i->rem;')
377         _c('    i->data = (%s *) child.data;', self.c_type)
378         _c('    i->index = child.index;')
379     else:
380         _c('    --i->rem;')
381         _c('    ++i->data;')
382         _c('    i->index += sizeof(%s);', self.c_type)
383
384     _c('}')
385
386     _h('')
387     _h('/**')
388     _h(' * Return the iterator pointing to the last element')
389     _h(' * @param i An %s', self.c_iterator_type)
390     _h(' * @return  The iterator pointing to the last element')
391     _h(' *')
392     _h(' * Set the current element in the iterator to the last element.')
393     _h(' * The member rem is set to 0. The member data points to the')
394     _h(' * last element.')
395     _h(' */')
396     _c('')
397     _hc('')
398     _hc('/*****************************************************************************')
399     _hc(' **')
400     _hc(' ** xcb_generic_iterator_t %s', self.c_end_name)
401     _hc(' ** ')
402     _hc(' ** @param %s i', self.c_iterator_type)
403     _hc(' ** @returns xcb_generic_iterator_t')
404     _hc(' **')
405     _hc(' *****************************************************************************/')
406     _hc(' ')
407     _hc('xcb_generic_iterator_t')
408     _h('%s (%s i  /**< */);', self.c_end_name, self.c_iterator_type)
409     _c('%s (%s i  /**< */)', self.c_end_name, self.c_iterator_type)
410     _c('{')
411     _c('    xcb_generic_iterator_t ret;')
412
413     if self.fixed_size():
414         _c('    ret.data = i.data + i.rem;')
415         _c('    ret.index = i.index + ((char *) ret.data - (char *) i.data);')
416         _c('    ret.rem = 0;')
417     else:
418         _c('    while(i.rem > 0)')
419         _c('        %s(&i);', self.c_next_name)
420         _c('    ret.data = i.data;')
421         _c('    ret.rem = i.rem;')
422         _c('    ret.index = i.index;')
423
424     _c('    return ret;')
425     _c('}')
426
427 def _c_accessor_get_length(expr, prefix=''):
428     '''
429     Figures out what C code is needed to get a length field.
430     For fields that follow a variable-length field, use the accessor.
431     Otherwise, just reference the structure field directly.
432     '''
433     prefarrow = '' if prefix == '' else prefix + '->'
434
435     if expr.lenfield != None and expr.lenfield.prev_varsized_field != None:
436         return expr.lenfield.c_accessor_name + '(' + prefix + ')'
437     elif expr.lenfield_name != None:
438         return prefarrow + expr.lenfield_name
439     else:
440         return str(expr.nmemb)
441
442 def _c_accessor_get_expr(expr, prefix=''):
443     '''
444     Figures out what C code is needed to get the length of a list field.
445     Recurses for math operations.
446     Returns bitcount for value-mask fields.
447     Otherwise, uses the value of the length field.
448     '''
449     lenexp = _c_accessor_get_length(expr, prefix)
450
451     if expr.op != None:
452         return '(' + _c_accessor_get_expr(expr.lhs, prefix) + ' ' + expr.op + ' ' + _c_accessor_get_expr(expr.rhs, prefix) + ')'
453     elif expr.bitfield:
454         return 'xcb_popcount(' + lenexp + ')'
455     else:
456         return lenexp
457
458 def _c_accessors_field(self, field):
459     '''
460     Declares the accessor functions for a non-list field that follows a variable-length field.
461     '''
462     if field.type.is_simple:
463         _hc('')
464         _hc('')
465         _hc('/*****************************************************************************')
466         _hc(' **')
467         _hc(' ** %s %s', field.c_field_type, field.c_accessor_name)
468         _hc(' ** ')
469         _hc(' ** @param const %s *R', self.c_type)
470         _hc(' ** @returns %s', field.c_field_type)
471         _hc(' **')
472         _hc(' *****************************************************************************/')
473         _hc(' ')
474         _hc('%s', field.c_field_type)
475         _h('%s (const %s *R  /**< */);', field.c_accessor_name, self.c_type)
476         _c('%s (const %s *R  /**< */)', field.c_accessor_name, self.c_type)
477         _c('{')
478         _c('    xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
479         _c('    return * (%s *) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index) + %d);', field.c_field_type, field.first_field_after_varsized.type.c_type, field.prev_varsized_offset)
480         _c('}')
481     else:
482         _hc('')
483         _hc('')
484         _hc('/*****************************************************************************')
485         _hc(' **')
486         _hc(' ** %s * %s', field.c_field_type, field.c_accessor_name)
487         _hc(' ** ')
488         _hc(' ** @param const %s *R', self.c_type)
489         _hc(' ** @returns %s *', field.c_field_type)
490         _hc(' **')
491         _hc(' *****************************************************************************/')
492         _hc(' ')
493         _hc('%s *', field.c_field_type)
494         _h('%s (const %s *R  /**< */);', field.c_accessor_name, self.c_type)
495         _c('%s (const %s *R  /**< */)', field.c_accessor_name, self.c_type)
496         _c('{')
497         _c('    xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
498         _c('    return (%s *) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index) + %d);', field.c_field_type, field.first_field_after_varsized.type.c_type, field.prev_varsized_offset)
499         _c('}')
500     
501 def _c_accessors_list(self, field):
502     '''
503     Declares the accessor functions for a list field.
504     Declares a direct-accessor function only if the list members are fixed size.
505     Declares length and get-iterator functions always.
506     '''
507     list = field.type
508
509     _h_setlevel(1)
510     _c_setlevel(1)
511     if list.member.fixed_size():
512         _hc('')
513         _hc('')
514         _hc('/*****************************************************************************')
515         _hc(' **')
516         _hc(' ** %s * %s', field.c_field_type, field.c_accessor_name)
517         _hc(' ** ')
518         _hc(' ** @param const %s *R', self.c_type)
519         _hc(' ** @returns %s *', field.c_field_type)
520         _hc(' **')
521         _hc(' *****************************************************************************/')
522         _hc(' ')
523         _hc('%s *', field.c_field_type)
524         _h('%s (const %s *R  /**< */);', field.c_accessor_name, self.c_type)
525         _c('%s (const %s *R  /**< */)', field.c_accessor_name, self.c_type)
526         _c('{')
527
528         if field.prev_varsized_field == None:
529             _c('    return (%s *) (R + 1);', field.c_field_type)
530         else:
531             _c('    xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
532             _c('    return (%s *) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index) + %d);', field.c_field_type, field.first_field_after_varsized.type.c_type, field.prev_varsized_offset)
533
534         _c('}')
535
536     _hc('')
537     _hc('')
538     _hc('/*****************************************************************************')
539     _hc(' **')
540     _hc(' ** int %s', field.c_length_name)
541     _hc(' ** ')
542     _hc(' ** @param const %s *R', self.c_type)
543     _hc(' ** @returns int')
544     _hc(' **')
545     _hc(' *****************************************************************************/')
546     _hc(' ')
547     _hc('int')
548     _h('%s (const %s *R  /**< */);', field.c_length_name, self.c_type)
549     _c('%s (const %s *R  /**< */)', field.c_length_name, self.c_type)
550     _c('{')
551     _c('    return %s;', _c_accessor_get_expr(field.type.expr, 'R'))
552     _c('}')
553
554     if field.type.member.is_simple:
555         _hc('')
556         _hc('')
557         _hc('/*****************************************************************************')
558         _hc(' **')
559         _hc(' ** xcb_generic_iterator_t %s', field.c_end_name)
560         _hc(' ** ')
561         _hc(' ** @param const %s *R', self.c_type)
562         _hc(' ** @returns xcb_generic_iterator_t')
563         _hc(' **')
564         _hc(' *****************************************************************************/')
565         _hc(' ')
566         _hc('xcb_generic_iterator_t')
567         _h('%s (const %s *R  /**< */);', field.c_end_name, self.c_type)
568         _c('%s (const %s *R  /**< */)', field.c_end_name, self.c_type)
569         _c('{')
570         _c('    xcb_generic_iterator_t i;')
571
572         if field.prev_varsized_field == None:
573             _c('    i.data = ((%s *) (R + 1)) + (%s);', field.type.c_wiretype, _c_accessor_get_expr(field.type.expr, 'R'))
574         else:
575             _c('    xcb_generic_iterator_t child = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
576             _c('    i.data = ((%s *) child.data) + (%s);', field.type.c_wiretype, _c_accessor_get_expr(field.type.expr, 'R'))
577
578         _c('    i.rem = 0;')
579         _c('    i.index = (char *) i.data - (char *) R;')
580         _c('    return i;')
581         _c('}')
582
583     else:
584         _hc('')
585         _hc('')
586         _hc('/*****************************************************************************')
587         _hc(' **')
588         _hc(' ** %s %s', field.c_iterator_type, field.c_iterator_name)
589         _hc(' ** ')
590         _hc(' ** @param const %s *R', self.c_type)
591         _hc(' ** @returns %s', field.c_iterator_type)
592         _hc(' **')
593         _hc(' *****************************************************************************/')
594         _hc(' ')
595         _hc('%s', field.c_iterator_type)
596         _h('%s (const %s *R  /**< */);', field.c_iterator_name, self.c_type)
597         _c('%s (const %s *R  /**< */)', field.c_iterator_name, self.c_type)
598         _c('{')
599         _c('    %s i;', field.c_iterator_type)
600
601         if field.prev_varsized_field == None:
602             _c('    i.data = (%s *) (R + 1);', field.c_field_type)
603         else:
604             _c('    xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
605             _c('    i.data = (%s *) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index));', field.c_field_type, field.c_field_type)
606
607         _c('    i.rem = %s;', _c_accessor_get_expr(field.type.expr, 'R'))
608         _c('    i.index = (char *) i.data - (char *) R;')
609         _c('    return i;')
610         _c('}')
611
612 def _c_accessors(self, name, base):
613     '''
614     Declares the accessor functions for the fields of a structure.
615     '''
616     for field in self.fields:
617         if field.type.is_list and not field.type.fixed_size():
618             _c_accessors_list(self, field)
619         elif field.prev_varsized_field != None:
620             _c_accessors_field(self, field)
621
622 def c_simple(self, name):
623     '''
624     Exported function that handles cardinal type declarations.
625     These are types which are typedef'd to one of the CARDx's, char, float, etc.
626     '''
627     _c_type_setup(self, name, ())
628
629     if (self.name != name):
630         # Typedef
631         _h_setlevel(0)
632         my_name = _t(name)
633         _h('')
634         _h('typedef %s %s;', _t(self.name), my_name)
635
636         # Iterator
637         _c_iterator(self, name)
638
639 def _c_complex(self):
640     '''
641     Helper function for handling all structure types.
642     Called for all structs, requests, replies, events, errors.
643     '''
644     _h_setlevel(0)
645     _h('')
646     _h('/**')
647     _h(' * @brief %s', self.c_type)
648     _h(' **/')
649     _h('typedef %s %s {', self.c_container, self.c_type)
650
651     struct_fields = []
652     maxtypelen = 0
653
654     varfield = None
655     for field in self.fields:
656         if not field.type.fixed_size():
657             varfield = field.c_field_name
658             continue
659         if varfield != None and not field.type.is_pad and field.wire:
660             errmsg = '%s: warning: variable field %s followed by fixed field %s\n' % (self.c_type, varfield, field.c_field_name)
661             sys.stderr.write(errmsg)
662             # sys.exit(1)
663         if field.wire:
664             struct_fields.append(field)
665         
666     for field in struct_fields:
667         if len(field.c_field_type) > maxtypelen:
668             maxtypelen = len(field.c_field_type)
669
670     for field in struct_fields:
671         spacing = ' ' * (maxtypelen - len(field.c_field_type))
672         _h('    %s%s %s%s; /**<  */', field.c_field_type, spacing, field.c_field_name, field.c_subscript)
673
674     _h('} %s;', self.c_type)
675
676 def c_struct(self, name):
677     '''
678     Exported function that handles structure declarations.
679     '''
680     _c_type_setup(self, name, ())
681     _c_complex(self)
682     _c_accessors(self, name, name)
683     _c_iterator(self, name)
684
685 def c_union(self, name):
686     '''
687     Exported function that handles union declarations.
688     '''
689     _c_type_setup(self, name, ())
690     _c_complex(self)
691     _c_iterator(self, name)
692
693 def _c_request_helper(self, name, cookie_type, void, regular):
694     '''
695     Declares a request function.
696     '''
697
698     # Four stunningly confusing possibilities here:
699     #
700     #   Void            Non-void
701     # ------------------------------
702     # "req"            "req"
703     # 0 flag           CHECKED flag   Normal Mode
704     # void_cookie      req_cookie
705     # ------------------------------
706     # "req_checked"    "req_unchecked"
707     # CHECKED flag     0 flag         Abnormal Mode
708     # void_cookie      req_cookie
709     # ------------------------------
710
711
712     # Whether we are _checked or _unchecked
713     checked = void and not regular
714     unchecked = not void and not regular
715
716     # What kind of cookie we return
717     func_cookie = 'xcb_void_cookie_t' if void else self.c_cookie_type
718
719     # What flag is passed to xcb_request
720     func_flags = '0' if (void and regular) or (not void and not regular) else 'XCB_REQUEST_CHECKED'
721
722     # Global extension id variable or NULL for xproto
723     func_ext_global = '&' + _ns.c_ext_global_name if _ns.is_ext else '0'
724
725     # What our function name is
726     func_name = self.c_request_name
727     if checked:
728         func_name = self.c_checked_name
729     if unchecked:
730         func_name = self.c_unchecked_name
731
732     param_fields = []
733     wire_fields = []
734     maxtypelen = len('xcb_connection_t')
735
736     for field in self.fields:
737         if field.visible:
738             # The field should appear as a call parameter
739             param_fields.append(field)
740         if field.wire and not field.auto:
741             # We need to set the field up in the structure
742             wire_fields.append(field)
743         
744     for field in param_fields:
745         if len(field.c_field_const_type) > maxtypelen:
746             maxtypelen = len(field.c_field_const_type)
747
748     _h_setlevel(1)
749     _c_setlevel(1)
750     _h('')
751     _h('/**')
752     _h(' * Delivers a request to the X server')
753     _h(' * @param c The connection')
754     _h(' * @return A cookie')
755     _h(' *')
756     _h(' * Delivers a request to the X server.')
757     _h(' * ')
758     if checked:
759         _h(' * This form can be used only if the request will not cause')
760         _h(' * a reply to be generated. Any returned error will be')
761         _h(' * saved for handling by xcb_request_check().')
762     if unchecked:
763         _h(' * This form can be used only if the request will cause')
764         _h(' * a reply to be generated. Any returned error will be')
765         _h(' * placed in the event queue.')
766     _h(' */')
767     _c('')
768     _hc('')
769     _hc('/*****************************************************************************')
770     _hc(' **')
771     _hc(' ** %s %s', cookie_type, func_name)
772     _hc(' ** ')
773
774     spacing = ' ' * (maxtypelen - len('xcb_connection_t'))
775     _hc(' ** @param xcb_connection_t%s *c', spacing)
776
777     for field in param_fields:
778         spacing = ' ' * (maxtypelen - len(field.c_field_const_type))
779         _hc(' ** @param %s%s %s%s', field.c_field_const_type, spacing, field.c_pointer, field.c_field_name)
780
781     _hc(' ** @returns %s', cookie_type)
782     _hc(' **')
783     _hc(' *****************************************************************************/')
784     _hc(' ')
785     _hc('%s', cookie_type)
786
787     spacing = ' ' * (maxtypelen - len('xcb_connection_t'))
788     comma = ',' if len(param_fields) else ');'
789     _h('%s (xcb_connection_t%s *c  /**< */%s', func_name, spacing, comma)
790     comma = ',' if len(param_fields) else ')'
791     _c('%s (xcb_connection_t%s *c  /**< */%s', func_name, spacing, comma)
792
793     func_spacing = ' ' * (len(func_name) + 2)
794     count = len(param_fields)
795     for field in param_fields:
796         count = count - 1
797         spacing = ' ' * (maxtypelen - len(field.c_field_const_type))
798         comma = ',' if count else ');'
799         _h('%s%s%s %s%s  /**< */%s', func_spacing, field.c_field_const_type, spacing, field.c_pointer, field.c_field_name, comma)
800         comma = ',' if count else ')'
801         _c('%s%s%s %s%s  /**< */%s', func_spacing, field.c_field_const_type, spacing, field.c_pointer, field.c_field_name, comma)
802
803     count = 2
804     for field in param_fields:
805         if not field.type.fixed_size():
806             count = count + 2
807
808     _c('{')
809     _c('    static const xcb_protocol_request_t xcb_req = {')
810     _c('        /* count */ %d,', count)
811     _c('        /* ext */ %s,', func_ext_global)
812     _c('        /* opcode */ %s,', self.c_request_name.upper())
813     _c('        /* isvoid */ %d', 1 if void else 0)
814     _c('    };')
815     _c('    ')
816     _c('    struct iovec xcb_parts[%d];', count + 2)
817     _c('    %s xcb_ret;', func_cookie)
818     _c('    %s xcb_out;', self.c_type)
819     _c('    ')
820
821     for field in wire_fields:
822         if field.type.fixed_size():
823             if field.type.is_expr:
824                 _c('    xcb_out.%s = %s;', field.c_field_name, _c_accessor_get_expr(field.type.expr))
825
826             elif field.type.is_pad:
827                 if field.type.nmemb == 1:
828                     _c('    xcb_out.%s = 0;', field.c_field_name)
829                 else:
830                     _c('    memset(xcb_out.%s, 0, %d);', field.c_field_name, field.type.nmemb)
831             else:
832                 if field.type.nmemb == 1:
833                     _c('    xcb_out.%s = %s;', field.c_field_name, field.c_field_name)
834                 else:
835                     _c('    memcpy(xcb_out.%s, %s, %d);', field.c_field_name, field.c_field_name, field.type.nmemb)
836
837     _c('    ')
838     _c('    xcb_parts[2].iov_base = (char *) &xcb_out;')
839     _c('    xcb_parts[2].iov_len = sizeof(xcb_out);')
840     _c('    xcb_parts[3].iov_base = 0;')
841     _c('    xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;')
842
843     count = 4
844     for field in param_fields:
845         if not field.type.fixed_size():
846             _c('    xcb_parts[%d].iov_base = (char *) %s;', count, field.c_field_name)
847             if field.type.is_list:
848                 _c('    xcb_parts[%d].iov_len = %s * sizeof(%s);', count, _c_accessor_get_expr(field.type.expr), field.type.member.c_wiretype)
849             else:
850                 _c('    xcb_parts[%d].iov_len = %s * sizeof(%s);', count, 'Uh oh', field.type.c_wiretype)
851             _c('    xcb_parts[%d].iov_base = 0;', count + 1)
852             _c('    xcb_parts[%d].iov_len = -xcb_parts[%d].iov_len & 3;', count + 1, count)
853             count = count + 2
854
855     _c('    xcb_ret.sequence = xcb_send_request(c, %s, xcb_parts + 2, &xcb_req);', func_flags)
856     _c('    return xcb_ret;')
857     _c('}')
858
859 def _c_reply(self, name):
860     '''
861     Declares the function that returns the reply structure.
862     '''
863     spacing1 = ' ' * (len(self.c_cookie_type) - len('xcb_connection_t'))
864     spacing2 = ' ' * (len(self.c_cookie_type) - len('xcb_generic_error_t'))
865     spacing3 = ' ' * (len(self.c_reply_name) + 2)
866
867     _h('')
868     _h('/**')
869     _h(' * Return the reply')
870     _h(' * @param c      The connection')
871     _h(' * @param cookie The cookie')
872     _h(' * @param e      The xcb_generic_error_t supplied')
873     _h(' *')
874     _h(' * Returns the reply of the request asked by')
875     _h(' * ')
876     _h(' * The parameter @p e supplied to this function must be NULL if')
877     _h(' * %s(). is used.', self.c_unchecked_name)
878     _h(' * Otherwise, it stores the error if any.')
879     _h(' *')
880     _h(' * The returned value must be freed by the caller using free().')
881     _h(' */')
882     _c('')
883     _hc('')
884     _hc('/*****************************************************************************')
885     _hc(' **')
886     _hc(' ** %s * %s', self.c_reply_type, self.c_reply_name)
887     _hc(' ** ')
888     _hc(' ** @param xcb_connection_t%s  *c', spacing1)
889     _hc(' ** @param %s   cookie', self.c_cookie_type)
890     _hc(' ** @param xcb_generic_error_t%s **e', spacing2)
891     _hc(' ** @returns %s *', self.c_reply_type)
892     _hc(' **')
893     _hc(' *****************************************************************************/')
894     _hc(' ')
895     _hc('%s *', self.c_reply_type)
896     _hc('%s (xcb_connection_t%s  *c  /**< */,', self.c_reply_name, spacing1)
897     _hc('%s%s   cookie  /**< */,', spacing3, self.c_cookie_type)
898     _h('%sxcb_generic_error_t%s **e  /**< */);', spacing3, spacing2)
899     _c('%sxcb_generic_error_t%s **e  /**< */)', spacing3, spacing2)
900     _c('{')
901     _c('    return (%s *) xcb_wait_for_reply(c, cookie.sequence, e);', self.c_reply_type)
902     _c('}')
903
904 def _c_opcode(name, opcode):
905     '''
906     Declares the opcode define for requests, events, and errors.
907     '''
908     _h_setlevel(0)
909     _h('')
910     _h('/** Opcode for %s. */', _n(name))
911     _h('#define %s %s', _n(name).upper(), opcode)
912     
913 def _c_cookie(self, name):
914     '''
915     Declares the cookie type for a non-void request.
916     '''
917     _h_setlevel(0)
918     _h('')
919     _h('/**')
920     _h(' * @brief %s', self.c_cookie_type)
921     _h(' **/')
922     _h('typedef struct %s {', self.c_cookie_type)
923     _h('    unsigned int sequence; /**<  */')
924     _h('} %s;', self.c_cookie_type)
925
926 def c_request(self, name):
927     '''
928     Exported function that handles request declarations.
929     '''
930     _c_type_setup(self, name, ('request',))
931
932     if self.reply:
933         # Cookie type declaration
934         _c_cookie(self, name)
935
936     # Opcode define
937     _c_opcode(name, self.opcode)
938
939     # Request structure declaration
940     _c_complex(self)
941
942     if self.reply:
943         _c_type_setup(self.reply, name, ('reply',))
944         # Reply structure definition
945         _c_complex(self.reply)
946         # Request prototypes
947         _c_request_helper(self, name, self.c_cookie_type, False, True)
948         _c_request_helper(self, name, self.c_cookie_type, False, False)
949         # Reply accessors
950         _c_accessors(self.reply, name + ('reply',), name)
951         _c_reply(self, name)
952     else:
953         # Request prototypes
954         _c_request_helper(self, name, 'xcb_void_cookie_t', True, False)
955         _c_request_helper(self, name, 'xcb_void_cookie_t', True, True)
956
957 def c_event(self, name):
958     '''
959     Exported function that handles event declarations.
960     '''
961     _c_type_setup(self, name, ('event',))
962
963     # Opcode define
964     _c_opcode(name, self.opcodes[name])
965
966     if self.name == name:
967         # Structure definition
968         _c_complex(self)
969     else:
970         # Typedef
971         _h('')
972         _h('typedef %s %s;', _t(self.name + ('event',)), _t(name + ('event',)))
973
974 def c_error(self, name):
975     '''
976     Exported function that handles error declarations.
977     '''
978     _c_type_setup(self, name, ('error',))
979
980     # Opcode define
981     _c_opcode(name, self.opcodes[name])
982
983     if self.name == name:
984         # Structure definition
985         _c_complex(self)
986     else:
987         # Typedef
988         _h('')
989         _h('typedef %s %s;', _t(self.name + ('error',)), _t(name + ('error',)))
990
991
992 # Main routine starts here
993
994 # Must create an "output" dictionary before any xcbgen imports.
995 output = {'open'    : c_open,
996           'close'   : c_close,
997           'simple'  : c_simple,
998           'enum'    : c_enum,
999           'struct'  : c_struct,
1000           'union'   : c_union,
1001           'request' : c_request,
1002           'event'   : c_event,
1003           'error'   : c_error
1004           }
1005
1006 # Boilerplate below this point
1007
1008 # Check for the argument that specifies path to the xcbgen python package.
1009 try:
1010     opts, args = getopt.getopt(sys.argv[1:], 'p:')
1011 except getopt.GetoptError, err:
1012     print str(err)
1013     print 'Usage: c_client.py [-p path] file.xml'
1014     sys.exit(1)
1015
1016 for (opt, arg) in opts:
1017     if opt == '-p':
1018         sys.path.append(arg)
1019
1020 # Import the module class
1021 try:
1022     from xcbgen.state import Module
1023 except ImportError:
1024     print ''
1025     print 'Failed to load the xcbgen Python package!'
1026     print 'Make sure that xcb/proto installed it on your Python path.'
1027     print 'If not, you will need to create a .pth file or define $PYTHONPATH'
1028     print 'to extend the path.'
1029     print 'Refer to the README file in xcb/proto for more info.'
1030     print ''
1031     raise
1032
1033 # Parse the xml header
1034 module = Module(args[0], output)
1035
1036 # Build type-registry and resolve type dependencies
1037 module.register()
1038 module.resolve()
1039
1040 # Output the code
1041 module.generate()