Merge branch 'master' of git://github.com/topcat/xcb-win32
[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 == '~':
452         return '(' + '~' + _c_accessor_get_expr(expr.rhs, prefix) + ')'
453     elif expr.op != None:
454         return '(' + _c_accessor_get_expr(expr.lhs, prefix) + ' ' + expr.op + ' ' + _c_accessor_get_expr(expr.rhs, prefix) + ')'
455     elif expr.bitfield:
456         return 'xcb_popcount(' + lenexp + ')'
457     else:
458         return lenexp
459
460 def _c_accessors_field(self, field):
461     '''
462     Declares the accessor functions for a non-list field that follows a variable-length field.
463     '''
464     if field.type.is_simple:
465         _hc('')
466         _hc('')
467         _hc('/*****************************************************************************')
468         _hc(' **')
469         _hc(' ** %s %s', field.c_field_type, field.c_accessor_name)
470         _hc(' ** ')
471         _hc(' ** @param const %s *R', self.c_type)
472         _hc(' ** @returns %s', field.c_field_type)
473         _hc(' **')
474         _hc(' *****************************************************************************/')
475         _hc(' ')
476         _hc('%s', field.c_field_type)
477         _h('%s (const %s *R  /**< */);', field.c_accessor_name, self.c_type)
478         _c('%s (const %s *R  /**< */)', field.c_accessor_name, self.c_type)
479         _c('{')
480         _c('    xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
481         _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)
482         _c('}')
483     else:
484         _hc('')
485         _hc('')
486         _hc('/*****************************************************************************')
487         _hc(' **')
488         _hc(' ** %s * %s', field.c_field_type, field.c_accessor_name)
489         _hc(' ** ')
490         _hc(' ** @param const %s *R', self.c_type)
491         _hc(' ** @returns %s *', field.c_field_type)
492         _hc(' **')
493         _hc(' *****************************************************************************/')
494         _hc(' ')
495         _hc('%s *', field.c_field_type)
496         _h('%s (const %s *R  /**< */);', field.c_accessor_name, self.c_type)
497         _c('%s (const %s *R  /**< */)', field.c_accessor_name, self.c_type)
498         _c('{')
499         _c('    xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
500         _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)
501         _c('}')
502     
503 def _c_accessors_list(self, field):
504     '''
505     Declares the accessor functions for a list field.
506     Declares a direct-accessor function only if the list members are fixed size.
507     Declares length and get-iterator functions always.
508     '''
509     list = field.type
510
511     _h_setlevel(1)
512     _c_setlevel(1)
513     if list.member.fixed_size():
514         _hc('')
515         _hc('')
516         _hc('/*****************************************************************************')
517         _hc(' **')
518         _hc(' ** %s * %s', field.c_field_type, field.c_accessor_name)
519         _hc(' ** ')
520         _hc(' ** @param const %s *R', self.c_type)
521         _hc(' ** @returns %s *', field.c_field_type)
522         _hc(' **')
523         _hc(' *****************************************************************************/')
524         _hc(' ')
525         _hc('%s *', field.c_field_type)
526         _h('%s (const %s *R  /**< */);', field.c_accessor_name, self.c_type)
527         _c('%s (const %s *R  /**< */)', field.c_accessor_name, self.c_type)
528         _c('{')
529
530         if field.prev_varsized_field == None:
531             _c('    return (%s *) (R + 1);', field.c_field_type)
532         else:
533             _c('    xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
534             _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)
535
536         _c('}')
537
538     _hc('')
539     _hc('')
540     _hc('/*****************************************************************************')
541     _hc(' **')
542     _hc(' ** int %s', field.c_length_name)
543     _hc(' ** ')
544     _hc(' ** @param const %s *R', self.c_type)
545     _hc(' ** @returns int')
546     _hc(' **')
547     _hc(' *****************************************************************************/')
548     _hc(' ')
549     _hc('int')
550     _h('%s (const %s *R  /**< */);', field.c_length_name, self.c_type)
551     _c('%s (const %s *R  /**< */)', field.c_length_name, self.c_type)
552     _c('{')
553     _c('    return %s;', _c_accessor_get_expr(field.type.expr, 'R'))
554     _c('}')
555
556     if field.type.member.is_simple:
557         _hc('')
558         _hc('')
559         _hc('/*****************************************************************************')
560         _hc(' **')
561         _hc(' ** xcb_generic_iterator_t %s', field.c_end_name)
562         _hc(' ** ')
563         _hc(' ** @param const %s *R', self.c_type)
564         _hc(' ** @returns xcb_generic_iterator_t')
565         _hc(' **')
566         _hc(' *****************************************************************************/')
567         _hc(' ')
568         _hc('xcb_generic_iterator_t')
569         _h('%s (const %s *R  /**< */);', field.c_end_name, self.c_type)
570         _c('%s (const %s *R  /**< */)', field.c_end_name, self.c_type)
571         _c('{')
572         _c('    xcb_generic_iterator_t i;')
573
574         if field.prev_varsized_field == None:
575             _c('    i.data = ((%s *) (R + 1)) + (%s);', field.type.c_wiretype, _c_accessor_get_expr(field.type.expr, 'R'))
576         else:
577             _c('    xcb_generic_iterator_t child = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
578             _c('    i.data = ((%s *) child.data) + (%s);', field.type.c_wiretype, _c_accessor_get_expr(field.type.expr, 'R'))
579
580         _c('    i.rem = 0;')
581         _c('    i.index = (char *) i.data - (char *) R;')
582         _c('    return i;')
583         _c('}')
584
585     else:
586         _hc('')
587         _hc('')
588         _hc('/*****************************************************************************')
589         _hc(' **')
590         _hc(' ** %s %s', field.c_iterator_type, field.c_iterator_name)
591         _hc(' ** ')
592         _hc(' ** @param const %s *R', self.c_type)
593         _hc(' ** @returns %s', field.c_iterator_type)
594         _hc(' **')
595         _hc(' *****************************************************************************/')
596         _hc(' ')
597         _hc('%s', field.c_iterator_type)
598         _h('%s (const %s *R  /**< */);', field.c_iterator_name, self.c_type)
599         _c('%s (const %s *R  /**< */)', field.c_iterator_name, self.c_type)
600         _c('{')
601         _c('    %s i;', field.c_iterator_type)
602
603         if field.prev_varsized_field == None:
604             _c('    i.data = (%s *) (R + 1);', field.c_field_type)
605         else:
606             _c('    xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
607             _c('    i.data = (%s *) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index));', field.c_field_type, field.c_field_type)
608
609         _c('    i.rem = %s;', _c_accessor_get_expr(field.type.expr, 'R'))
610         _c('    i.index = (char *) i.data - (char *) R;')
611         _c('    return i;')
612         _c('}')
613
614 def _c_accessors(self, name, base):
615     '''
616     Declares the accessor functions for the fields of a structure.
617     '''
618     for field in self.fields:
619         if field.type.is_list and not field.type.fixed_size():
620             _c_accessors_list(self, field)
621         elif field.prev_varsized_field != None:
622             _c_accessors_field(self, field)
623
624 def c_simple(self, name):
625     '''
626     Exported function that handles cardinal type declarations.
627     These are types which are typedef'd to one of the CARDx's, char, float, etc.
628     '''
629     _c_type_setup(self, name, ())
630
631     if (self.name != name):
632         # Typedef
633         _h_setlevel(0)
634         my_name = _t(name)
635         _h('')
636         _h('typedef %s %s;', _t(self.name), my_name)
637
638         # Iterator
639         _c_iterator(self, name)
640
641 def _c_complex(self):
642     '''
643     Helper function for handling all structure types.
644     Called for all structs, requests, replies, events, errors.
645     '''
646     _h_setlevel(0)
647     _h('')
648     _h('/**')
649     _h(' * @brief %s', self.c_type)
650     _h(' **/')
651     _h('typedef %s %s {', self.c_container, self.c_type)
652
653     struct_fields = []
654     maxtypelen = 0
655
656     varfield = None
657     for field in self.fields:
658         if not field.type.fixed_size():
659             varfield = field.c_field_name
660             continue
661         if varfield != None and not field.type.is_pad and field.wire:
662             errmsg = '%s: warning: variable field %s followed by fixed field %s\n' % (self.c_type, varfield, field.c_field_name)
663             sys.stderr.write(errmsg)
664             # sys.exit(1)
665         if field.wire:
666             struct_fields.append(field)
667         
668     for field in struct_fields:
669         if len(field.c_field_type) > maxtypelen:
670             maxtypelen = len(field.c_field_type)
671
672     for field in struct_fields:
673         spacing = ' ' * (maxtypelen - len(field.c_field_type))
674         _h('    %s%s %s%s; /**<  */', field.c_field_type, spacing, field.c_field_name, field.c_subscript)
675
676     _h('} %s;', self.c_type)
677
678 def c_struct(self, name):
679     '''
680     Exported function that handles structure declarations.
681     '''
682     _c_type_setup(self, name, ())
683     _c_complex(self)
684     _c_accessors(self, name, name)
685     _c_iterator(self, name)
686
687 def c_union(self, name):
688     '''
689     Exported function that handles union declarations.
690     '''
691     _c_type_setup(self, name, ())
692     _c_complex(self)
693     _c_iterator(self, name)
694
695 def _c_request_helper(self, name, cookie_type, void, regular):
696     '''
697     Declares a request function.
698     '''
699
700     # Four stunningly confusing possibilities here:
701     #
702     #   Void            Non-void
703     # ------------------------------
704     # "req"            "req"
705     # 0 flag           CHECKED flag   Normal Mode
706     # void_cookie      req_cookie
707     # ------------------------------
708     # "req_checked"    "req_unchecked"
709     # CHECKED flag     0 flag         Abnormal Mode
710     # void_cookie      req_cookie
711     # ------------------------------
712
713
714     # Whether we are _checked or _unchecked
715     checked = void and not regular
716     unchecked = not void and not regular
717
718     # What kind of cookie we return
719     func_cookie = 'xcb_void_cookie_t' if void else self.c_cookie_type
720
721     # What flag is passed to xcb_request
722     func_flags = '0' if (void and regular) or (not void and not regular) else 'XCB_REQUEST_CHECKED'
723
724     # Global extension id variable or NULL for xproto
725     func_ext_global = '&' + _ns.c_ext_global_name if _ns.is_ext else '0'
726
727     # What our function name is
728     func_name = self.c_request_name
729     if checked:
730         func_name = self.c_checked_name
731     if unchecked:
732         func_name = self.c_unchecked_name
733
734     param_fields = []
735     wire_fields = []
736     maxtypelen = len('xcb_connection_t')
737
738     for field in self.fields:
739         if field.visible:
740             # The field should appear as a call parameter
741             param_fields.append(field)
742         if field.wire and not field.auto:
743             # We need to set the field up in the structure
744             wire_fields.append(field)
745         
746     for field in param_fields:
747         if len(field.c_field_const_type) > maxtypelen:
748             maxtypelen = len(field.c_field_const_type)
749
750     _h_setlevel(1)
751     _c_setlevel(1)
752     _h('')
753     _h('/**')
754     _h(' * Delivers a request to the X server')
755     _h(' * @param c The connection')
756     _h(' * @return A cookie')
757     _h(' *')
758     _h(' * Delivers a request to the X server.')
759     _h(' * ')
760     if checked:
761         _h(' * This form can be used only if the request will not cause')
762         _h(' * a reply to be generated. Any returned error will be')
763         _h(' * saved for handling by xcb_request_check().')
764     if unchecked:
765         _h(' * This form can be used only if the request will cause')
766         _h(' * a reply to be generated. Any returned error will be')
767         _h(' * placed in the event queue.')
768     _h(' */')
769     _c('')
770     _hc('')
771     _hc('/*****************************************************************************')
772     _hc(' **')
773     _hc(' ** %s %s', cookie_type, func_name)
774     _hc(' ** ')
775
776     spacing = ' ' * (maxtypelen - len('xcb_connection_t'))
777     _hc(' ** @param xcb_connection_t%s *c', spacing)
778
779     for field in param_fields:
780         spacing = ' ' * (maxtypelen - len(field.c_field_const_type))
781         _hc(' ** @param %s%s %s%s', field.c_field_const_type, spacing, field.c_pointer, field.c_field_name)
782
783     _hc(' ** @returns %s', cookie_type)
784     _hc(' **')
785     _hc(' *****************************************************************************/')
786     _hc(' ')
787     _hc('%s', cookie_type)
788
789     spacing = ' ' * (maxtypelen - len('xcb_connection_t'))
790     comma = ',' if len(param_fields) else ');'
791     _h('%s (xcb_connection_t%s *c  /**< */%s', func_name, spacing, comma)
792     comma = ',' if len(param_fields) else ')'
793     _c('%s (xcb_connection_t%s *c  /**< */%s', func_name, spacing, comma)
794
795     func_spacing = ' ' * (len(func_name) + 2)
796     count = len(param_fields)
797     for field in param_fields:
798         count = count - 1
799         spacing = ' ' * (maxtypelen - len(field.c_field_const_type))
800         comma = ',' if count else ');'
801         _h('%s%s%s %s%s  /**< */%s', func_spacing, field.c_field_const_type, spacing, field.c_pointer, field.c_field_name, comma)
802         comma = ',' if count else ')'
803         _c('%s%s%s %s%s  /**< */%s', func_spacing, field.c_field_const_type, spacing, field.c_pointer, field.c_field_name, comma)
804
805     count = 2
806     for field in param_fields:
807         if not field.type.fixed_size():
808             count = count + 2
809
810     _c('{')
811     _c('    static const xcb_protocol_request_t xcb_req = {')
812     _c('        /* count */ %d,', count)
813     _c('        /* ext */ %s,', func_ext_global)
814     _c('        /* opcode */ %s,', self.c_request_name.upper())
815     _c('        /* isvoid */ %d', 1 if void else 0)
816     _c('    };')
817     _c('    ')
818     _c('    struct iovec xcb_parts[%d];', count + 2)
819     _c('    %s xcb_ret;', func_cookie)
820     _c('    %s xcb_out;', self.c_type)
821     _c('    ')
822
823     for field in wire_fields:
824         if field.type.fixed_size():
825             if field.type.is_expr:
826                 _c('    xcb_out.%s = %s;', field.c_field_name, _c_accessor_get_expr(field.type.expr))
827
828             elif field.type.is_pad:
829                 if field.type.nmemb == 1:
830                     _c('    xcb_out.%s = 0;', field.c_field_name)
831                 else:
832                     _c('    memset(xcb_out.%s, 0, %d);', field.c_field_name, field.type.nmemb)
833             else:
834                 if field.type.nmemb == 1:
835                     _c('    xcb_out.%s = %s;', field.c_field_name, field.c_field_name)
836                 else:
837                     _c('    memcpy(xcb_out.%s, %s, %d);', field.c_field_name, field.c_field_name, field.type.nmemb)
838
839     _c('    ')
840     _c('    xcb_parts[2].iov_base = (char *) &xcb_out;')
841     _c('    xcb_parts[2].iov_len = sizeof(xcb_out);')
842     _c('    xcb_parts[3].iov_base = 0;')
843     _c('    xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;')
844
845     count = 4
846     for field in param_fields:
847         if not field.type.fixed_size():
848             _c('    xcb_parts[%d].iov_base = (char *) %s;', count, field.c_field_name)
849             if field.type.is_list:
850                 _c('    xcb_parts[%d].iov_len = %s * sizeof(%s);', count, _c_accessor_get_expr(field.type.expr), field.type.member.c_wiretype)
851             else:
852                 _c('    xcb_parts[%d].iov_len = %s * sizeof(%s);', count, 'Uh oh', field.type.c_wiretype)
853             _c('    xcb_parts[%d].iov_base = 0;', count + 1)
854             _c('    xcb_parts[%d].iov_len = -xcb_parts[%d].iov_len & 3;', count + 1, count)
855             count = count + 2
856
857     _c('    xcb_ret.sequence = xcb_send_request(c, %s, xcb_parts + 2, &xcb_req);', func_flags)
858     _c('    return xcb_ret;')
859     _c('}')
860
861 def _c_reply(self, name):
862     '''
863     Declares the function that returns the reply structure.
864     '''
865     spacing1 = ' ' * (len(self.c_cookie_type) - len('xcb_connection_t'))
866     spacing2 = ' ' * (len(self.c_cookie_type) - len('xcb_generic_error_t'))
867     spacing3 = ' ' * (len(self.c_reply_name) + 2)
868
869     _h('')
870     _h('/**')
871     _h(' * Return the reply')
872     _h(' * @param c      The connection')
873     _h(' * @param cookie The cookie')
874     _h(' * @param e      The xcb_generic_error_t supplied')
875     _h(' *')
876     _h(' * Returns the reply of the request asked by')
877     _h(' * ')
878     _h(' * The parameter @p e supplied to this function must be NULL if')
879     _h(' * %s(). is used.', self.c_unchecked_name)
880     _h(' * Otherwise, it stores the error if any.')
881     _h(' *')
882     _h(' * The returned value must be freed by the caller using free().')
883     _h(' */')
884     _c('')
885     _hc('')
886     _hc('/*****************************************************************************')
887     _hc(' **')
888     _hc(' ** %s * %s', self.c_reply_type, self.c_reply_name)
889     _hc(' ** ')
890     _hc(' ** @param xcb_connection_t%s  *c', spacing1)
891     _hc(' ** @param %s   cookie', self.c_cookie_type)
892     _hc(' ** @param xcb_generic_error_t%s **e', spacing2)
893     _hc(' ** @returns %s *', self.c_reply_type)
894     _hc(' **')
895     _hc(' *****************************************************************************/')
896     _hc(' ')
897     _hc('%s *', self.c_reply_type)
898     _hc('%s (xcb_connection_t%s  *c  /**< */,', self.c_reply_name, spacing1)
899     _hc('%s%s   cookie  /**< */,', spacing3, self.c_cookie_type)
900     _h('%sxcb_generic_error_t%s **e  /**< */);', spacing3, spacing2)
901     _c('%sxcb_generic_error_t%s **e  /**< */)', spacing3, spacing2)
902     _c('{')
903     _c('    return (%s *) xcb_wait_for_reply(c, cookie.sequence, e);', self.c_reply_type)
904     _c('}')
905
906 def _c_opcode(name, opcode):
907     '''
908     Declares the opcode define for requests, events, and errors.
909     '''
910     _h_setlevel(0)
911     _h('')
912     _h('/** Opcode for %s. */', _n(name))
913     _h('#define %s %s', _n(name).upper(), opcode)
914     
915 def _c_cookie(self, name):
916     '''
917     Declares the cookie type for a non-void request.
918     '''
919     _h_setlevel(0)
920     _h('')
921     _h('/**')
922     _h(' * @brief %s', self.c_cookie_type)
923     _h(' **/')
924     _h('typedef struct %s {', self.c_cookie_type)
925     _h('    unsigned int sequence; /**<  */')
926     _h('} %s;', self.c_cookie_type)
927
928 def c_request(self, name):
929     '''
930     Exported function that handles request declarations.
931     '''
932     _c_type_setup(self, name, ('request',))
933
934     if self.reply:
935         # Cookie type declaration
936         _c_cookie(self, name)
937
938     # Opcode define
939     _c_opcode(name, self.opcode)
940
941     # Request structure declaration
942     _c_complex(self)
943
944     if self.reply:
945         _c_type_setup(self.reply, name, ('reply',))
946         # Reply structure definition
947         _c_complex(self.reply)
948         # Request prototypes
949         _c_request_helper(self, name, self.c_cookie_type, False, True)
950         _c_request_helper(self, name, self.c_cookie_type, False, False)
951         # Reply accessors
952         _c_accessors(self.reply, name + ('reply',), name)
953         _c_reply(self, name)
954     else:
955         # Request prototypes
956         _c_request_helper(self, name, 'xcb_void_cookie_t', True, False)
957         _c_request_helper(self, name, 'xcb_void_cookie_t', True, True)
958
959 def c_event(self, name):
960     '''
961     Exported function that handles event declarations.
962     '''
963     _c_type_setup(self, name, ('event',))
964
965     # Opcode define
966     _c_opcode(name, self.opcodes[name])
967
968     if self.name == name:
969         # Structure definition
970         _c_complex(self)
971     else:
972         # Typedef
973         _h('')
974         _h('typedef %s %s;', _t(self.name + ('event',)), _t(name + ('event',)))
975
976 def c_error(self, name):
977     '''
978     Exported function that handles error declarations.
979     '''
980     _c_type_setup(self, name, ('error',))
981
982     # Opcode define
983     _c_opcode(name, self.opcodes[name])
984
985     if self.name == name:
986         # Structure definition
987         _c_complex(self)
988     else:
989         # Typedef
990         _h('')
991         _h('typedef %s %s;', _t(self.name + ('error',)), _t(name + ('error',)))
992
993
994 # Main routine starts here
995
996 # Must create an "output" dictionary before any xcbgen imports.
997 output = {'open'    : c_open,
998           'close'   : c_close,
999           'simple'  : c_simple,
1000           'enum'    : c_enum,
1001           'struct'  : c_struct,
1002           'union'   : c_union,
1003           'request' : c_request,
1004           'event'   : c_event,
1005           'error'   : c_error
1006           }
1007
1008 # Boilerplate below this point
1009
1010 # Check for the argument that specifies path to the xcbgen python package.
1011 try:
1012     opts, args = getopt.getopt(sys.argv[1:], 'p:')
1013 except getopt.GetoptError, err:
1014     print str(err)
1015     print 'Usage: c_client.py [-p path] file.xml'
1016     sys.exit(1)
1017
1018 for (opt, arg) in opts:
1019     if opt == '-p':
1020         sys.path.append(arg)
1021
1022 # Import the module class
1023 try:
1024     from xcbgen.state import Module
1025 except ImportError:
1026     print ''
1027     print 'Failed to load the xcbgen Python package!'
1028     print 'Make sure that xcb/proto installed it on your Python path.'
1029     print 'If not, you will need to create a .pth file or define $PYTHONPATH'
1030     print 'to extend the path.'
1031     print 'Refer to the README file in xcb/proto for more info.'
1032     print ''
1033     raise
1034
1035 # Parse the xml header
1036 module = Module(args[0], output)
1037
1038 # Build type-registry and resolve type dependencies
1039 module.register()
1040 module.resolve()
1041
1042 # Output the code
1043 module.generate()