c_client.py: remove useless 'today' variable
[free-sw/xcb/libxcb] / src / c_client.py
index 7280004..4f66b48 100644 (file)
@@ -190,7 +190,7 @@ def c_open(self):
     _c('#define ALIGNOF(type) offsetof(struct { char dummy; type member; }, member)')
 
     if _ns.is_ext:
     _c('#define ALIGNOF(type) offsetof(struct { char dummy; type member; }, member)')
 
     if _ns.is_ext:
-        for (n, h) in self.imports:
+        for (n, h) in self.direct_imports:
             _hc('#include "%s.h"', h)
 
     _h('')
             _hc('#include "%s.h"', h)
 
     _h('')
@@ -981,15 +981,22 @@ def _c_serialize_helper_fields(context, self,
 
         # fields with variable size
         else:
 
         # fields with variable size
         else:
-            # switch/bitcase: always calculate padding before and after variable sized fields
-            if need_padding or is_bitcase:
+            if field.type.is_pad:
+                # Variable length pad is <pad align= />
+                code_lines.append('%s    xcb_align_to = %d;' % (space, field.type.align))
                 count += _c_serialize_helper_insert_padding(context, code_lines, space, 
                 count += _c_serialize_helper_insert_padding(context, code_lines, space, 
+                                                        self.var_followed_by_fixed_fields)
+                continue
+            else:
+                # switch/bitcase: always calculate padding before and after variable sized fields
+                if need_padding or is_bitcase:
+                    count += _c_serialize_helper_insert_padding(context, code_lines, space,
                                                             self.var_followed_by_fixed_fields)
 
                                                             self.var_followed_by_fixed_fields)
 
-            value, length = _c_serialize_helper_fields_variable_size(context, self, field, 
-                                                                     code_lines, temp_vars, 
-                                                                     space, prefix)
-            prev_field_was_variable = True
+                value, length = _c_serialize_helper_fields_variable_size(context, self, field,
+                                                                         code_lines, temp_vars,
+                                                                         space, prefix)
+                prev_field_was_variable = True
         
         # save (un)serialization C code
         if '' != value:
         
         # save (un)serialization C code
         if '' != value:
@@ -1061,8 +1068,8 @@ def _c_serialize_helper(context, complex_type,
         if context in ('unserialize', 'unpack', 'sizeof') and not self.var_followed_by_fixed_fields:
             code_lines.append('%s    xcb_block_len += sizeof(%s);' % (space, self.c_type))
             code_lines.append('%s    xcb_tmp += xcb_block_len;' % space)
         if context in ('unserialize', 'unpack', 'sizeof') and not self.var_followed_by_fixed_fields:
             code_lines.append('%s    xcb_block_len += sizeof(%s);' % (space, self.c_type))
             code_lines.append('%s    xcb_tmp += xcb_block_len;' % space)
-            # probably not needed
-            #_c_serialize_helper_insert_padding(context, code_lines, space, False)
+            code_lines.append('%s    xcb_buffer_len += xcb_block_len;' % space)
+            code_lines.append('%s    xcb_block_len = 0;' % space)
 
         count += _c_serialize_helper_fields(context, self, 
                                             code_lines, temp_vars, 
 
         count += _c_serialize_helper_fields(context, self, 
                                             code_lines, temp_vars, 
@@ -1541,6 +1548,17 @@ def _c_accessors_list(self, field):
     Declares a direct-accessor function only if the list members are fixed size.
     Declares length and get-iterator functions always.
     '''
     Declares a direct-accessor function only if the list members are fixed size.
     Declares length and get-iterator functions always.
     '''
+
+    def get_align_pad(field):
+            prev = field.prev_varsized_field
+            prev_prev = field.prev_varsized_field.prev_varsized_field
+
+            if (prev.type.is_pad and prev.type.align > 0 and prev_prev is not None):
+                return (prev_prev, '((-prev.index) & (%d - 1))' % prev.type.align)
+            else:
+                return (prev, None)
+
+
     list = field.type
     c_type = self.c_type
 
     list = field.type
     c_type = self.c_type
 
@@ -1616,9 +1634,16 @@ def _c_accessors_list(self, field):
         elif field.prev_varsized_field is None:
             _c('    return (%s *) (R + 1);', field.c_field_type)
         else:
         elif field.prev_varsized_field is None:
             _c('    return (%s *) (R + 1);', field.c_field_type)
         else:
-            _c('    xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
-            _c('    return (%s *) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index) + %d);', 
-               field.c_field_type, type_pad_type(field.first_field_after_varsized.type.c_type), field.prev_varsized_offset)
+            (prev_varsized_field, align_pad) = get_align_pad(field)
+
+            if align_pad is None:
+                align_pad = ('XCB_TYPE_PAD(%s, prev.index)' %
+                    type_pad_type(field.first_field_after_varsized.type.c_type))
+
+            _c('    xcb_generic_iterator_t prev = %s;',
+                _c_iterator_get_end(prev_varsized_field, 'R'))
+            _c('    return (%s *) ((char *) prev.data + %s + %d);',
+               field.c_field_type, align_pad, field.prev_varsized_offset)
         _c('}')
 
     _hc('')
         _c('}')
 
     _hc('')
@@ -1720,9 +1745,17 @@ def _c_accessors_list(self, field):
         elif field.prev_varsized_field == None:
             _c('    i.data = (%s *) (R + 1);', field.c_field_type)
         else:
         elif field.prev_varsized_field == None:
             _c('    i.data = (%s *) (R + 1);', field.c_field_type)
         else:
-            _c('    xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
-            _c('    i.data = (%s *) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index));', 
-               field.c_field_type, type_pad_type(field.c_field_type))
+            (prev_varsized_field, align_pad) = get_align_pad(field)
+
+            if align_pad is None:
+                align_pad = ('XCB_TYPE_PAD(%s, prev.index)' %
+                    type_pad_type(field.c_field_type))
+
+            _c('    xcb_generic_iterator_t prev = %s;',
+                _c_iterator_get_end(prev_varsized_field, 'R'))
+            _c('    i.data = (%s *) ((char *) prev.data + %s);',
+                field.c_field_type, align_pad)
+
         if switch_obj is None:
             _c('    i.rem = %s;', _c_accessor_get_expr(field.type.expr, fields))
         _c('    i.index = (char *) i.data - (char *) %s;', 'R' if switch_obj is None else 'S' )
         if switch_obj is None:
             _c('    i.rem = %s;', _c_accessor_get_expr(field.type.expr, fields))
         _c('    i.index = (char *) i.data - (char *) %s;', 'R' if switch_obj is None else 'S' )
@@ -1740,10 +1773,11 @@ def _c_accessors(self, name, base):
 #    else:
     if True:
         for field in self.fields:
 #    else:
     if True:
         for field in self.fields:
-            if field.type.is_list and not field.type.fixed_size():
-                _c_accessors_list(self, field)
-            elif field.prev_varsized_field is not None or not field.type.fixed_size():
-                _c_accessors_field(self, field)
+            if not field.type.is_pad:
+                if field.type.is_list and not field.type.fixed_size():
+                    _c_accessors_list(self, field)
+                elif field.prev_varsized_field is not None or not field.type.fixed_size():
+                    _c_accessors_field(self, field)
 
 def c_simple(self, name):
     '''
 
 def c_simple(self, name):
     '''
@@ -1762,7 +1796,7 @@ def c_simple(self, name):
         # Iterator
         _c_iterator(self, name)
 
         # Iterator
         _c_iterator(self, name)
 
-def _c_complex(self):
+def _c_complex(self, force_packed = False):
     '''
     Helper function for handling all structure types.
     Called for all structs, requests, replies, events, errors.
     '''
     Helper function for handling all structure types.
     Called for all structs, requests, replies, events, errors.
@@ -1817,7 +1851,7 @@ def _c_complex(self):
             if b.type.has_name:
                 _h('    } %s;', b.c_field_name)
 
             if b.type.has_name:
                 _h('    } %s;', b.c_field_name)
 
-    _h('} %s;', self.c_type)
+    _h('} %s%s;', 'XCB_PACKED ' if force_packed else '', self.c_type)
 
 def c_struct(self, name):
     '''
 
 def c_struct(self, name):
     '''
@@ -2336,18 +2370,18 @@ def _man_request(self, name, cookie_type, void, aux):
     func_name = self.c_request_name if not aux else self.c_aux_name
 
     def create_link(linkname):
     func_name = self.c_request_name if not aux else self.c_aux_name
 
     def create_link(linkname):
-        name = 'man/%s.3' % linkname
+        name = 'man/%s.%s' % (linkname, section)
         if manpaths:
             sys.stdout.write(name)
         f = open(name, 'w')
         if manpaths:
             sys.stdout.write(name)
         f = open(name, 'w')
-        f.write('.so man3/%s.3' % func_name)
+        f.write('.so man%s/%s.%s' % (section, func_name, section))
         f.close()
 
     if manpaths:
         f.close()
 
     if manpaths:
-        sys.stdout.write('man/%s.3 ' % func_name)
+        sys.stdout.write('man/%s.%s ' % (func_name, section))
     # Our CWD is src/, so this will end up in src/man/
     # Our CWD is src/, so this will end up in src/man/
-    f = open('man/%s.3' % func_name, 'w')
-    f.write('.TH %s 3  %s "XCB" "XCB Requests"\n' % (func_name, today))
+    f = open('man/%s.%s' % (func_name, section), 'w')
+    f.write('.TH %s %s  "%s" "%s" "XCB Requests"\n' % (func_name, section, center_footer, left_footer))
     # Left-adjust instead of adjusting to both sides
     f.write('.ad l\n')
     f.write('.SH NAME\n')
     # Left-adjust instead of adjusting to both sides
     f.write('.ad l\n')
     f.write('.SH NAME\n')
@@ -2672,14 +2706,14 @@ def _man_request(self, name, cookie_type, void, aux):
                  'have to be handled in the event loop.\n\nIf you want to '
                  'handle errors directly with \\fIxcb_request_check\\fP '
                  'instead, use \\fI%s_checked\\fP. See '
                  'have to be handled in the event loop.\n\nIf you want to '
                  'handle errors directly with \\fIxcb_request_check\\fP '
                  'instead, use \\fI%s_checked\\fP. See '
-                 '\\fBxcb-requests(3)\\fP for details.\n') % (base_func_name))
+                 '\\fBxcb-requests(%s)\\fP for details.\n') % (base_func_name, section))
     else:
         f.write(('Returns an \\fI%s\\fP. Errors have to be handled when '
                  'calling the reply function \\fI%s\\fP.\n\nIf you want to '
                  'handle errors in the event loop instead, use '
     else:
         f.write(('Returns an \\fI%s\\fP. Errors have to be handled when '
                  'calling the reply function \\fI%s\\fP.\n\nIf you want to '
                  'handle errors in the event loop instead, use '
-                 '\\fI%s_unchecked\\fP. See \\fBxcb-requests(3)\\fP for '
+                 '\\fI%s_unchecked\\fP. See \\fBxcb-requests(%s)\\fP for '
                  'details.\n') %
                  'details.\n') %
-                (cookie_type, self.c_reply_name, base_func_name))
+                (cookie_type, self.c_reply_name, base_func_name, section))
     f.write('.SH ERRORS\n')
     if hasattr(self, "doc") and self.doc:
         for errtype, errtext in self.doc.errors.items():
     f.write('.SH ERRORS\n')
     if hasattr(self, "doc") and self.doc:
         for errtype, errtext in self.doc.errors.items():
@@ -2697,18 +2731,18 @@ def _man_request(self, name, cookie_type, void, aux):
         f.write('.fi\n')
     f.write('.SH SEE ALSO\n')
     if hasattr(self, "doc") and self.doc:
         f.write('.fi\n')
     f.write('.SH SEE ALSO\n')
     if hasattr(self, "doc") and self.doc:
-        see = ['.BR %s (3)' % 'xcb-requests']
+        see = ['.BR %s (%s)' % ('xcb-requests', section)]
         if self.doc.example:
         if self.doc.example:
-            see.append('.BR %s (3)' % 'xcb-examples')
+            see.append('.BR %s (%s)' % ('xcb-examples', section))
         for seename, seetype in self.doc.see.items():
             if seetype == 'program':
                 see.append('.BR %s (1)' % seename)
             elif seetype == 'event':
         for seename, seetype in self.doc.see.items():
             if seetype == 'program':
                 see.append('.BR %s (1)' % seename)
             elif seetype == 'event':
-                see.append('.BR %s (3)' % _t(('xcb', seename, 'event')))
+                see.append('.BR %s (%s)' % (_t(('xcb', seename, 'event')), section))
             elif seetype == 'request':
             elif seetype == 'request':
-                see.append('.BR %s (3)' % _n(('xcb', seename)))
+                see.append('.BR %s (%s)' % (_n(('xcb', seename)), section))
             elif seetype == 'function':
             elif seetype == 'function':
-                see.append('.BR %s (3)' % seename)
+                see.append('.BR %s (%s)' % (seename, section))
             else:
                 see.append('TODO: %s (type %s)' % (seename, seetype))
         f.write(',\n'.join(see) + '\n')
             else:
                 see.append('TODO: %s (type %s)' % (seename, seetype))
         f.write(',\n'.join(see) + '\n')
@@ -2718,10 +2752,10 @@ def _man_request(self, name, cookie_type, void, aux):
 
 def _man_event(self, name):
     if manpaths:
 
 def _man_event(self, name):
     if manpaths:
-        sys.stdout.write('man/%s.3 ' % self.c_type)
+        sys.stdout.write('man/%s.%s ' % (self.c_type, section))
     # Our CWD is src/, so this will end up in src/man/
     # Our CWD is src/, so this will end up in src/man/
-    f = open('man/%s.3' % self.c_type, 'w')
-    f.write('.TH %s 3  %s "XCB" "XCB Events"\n' % (self.c_type, today))
+    f = open('man/%s.%s' % (self.c_type, section), 'w')
+    f.write('.TH %s %s  "%s" "%s" "XCB Events"\n' % (self.c_type, section, center_footer, left_footer))
     # Left-adjust instead of adjusting to both sides
     f.write('.ad l\n')
     f.write('.SH NAME\n')
     # Left-adjust instead of adjusting to both sides
     f.write('.ad l\n')
     f.write('.SH NAME\n')
@@ -2827,18 +2861,18 @@ def _man_event(self, name):
         f.write('.fi\n')
     f.write('.SH SEE ALSO\n')
     if hasattr(self, "doc") and self.doc:
         f.write('.fi\n')
     f.write('.SH SEE ALSO\n')
     if hasattr(self, "doc") and self.doc:
-        see = ['.BR %s (3)' % 'xcb_generic_event_t']
+        see = ['.BR %s (%s)' % ('xcb_generic_event_t', section)]
         if self.doc.example:
         if self.doc.example:
-            see.append('.BR %s (3)' % 'xcb-examples')
+            see.append('.BR %s (%s)' % ('xcb-examples', section))
         for seename, seetype in self.doc.see.items():
             if seetype == 'program':
                 see.append('.BR %s (1)' % seename)
             elif seetype == 'event':
         for seename, seetype in self.doc.see.items():
             if seetype == 'program':
                 see.append('.BR %s (1)' % seename)
             elif seetype == 'event':
-                see.append('.BR %s (3)' % _t(('xcb', seename, 'event')))
+                see.append('.BR %s (%s)' % (_t(('xcb', seename, 'event')), section))
             elif seetype == 'request':
             elif seetype == 'request':
-                see.append('.BR %s (3)' % _n(('xcb', seename)))
+                see.append('.BR %s (%s)' % (_n(('xcb', seename)), section))
             elif seetype == 'function':
             elif seetype == 'function':
-                see.append('.BR %s (3)' % seename)
+                see.append('.BR %s (%s)' % (seename, section))
             else:
                 see.append('TODO: %s (type %s)' % (seename, seetype))
         f.write(',\n'.join(see) + '\n')
             else:
                 see.append('TODO: %s (type %s)' % (seename, seetype))
         f.write(',\n'.join(see) + '\n')
@@ -2902,6 +2936,7 @@ def c_event(self, name):
     # events while generating the structure for them. Otherwise we would read
     # garbage (the internal full_sequence) when accessing normal event fields
     # there.
     # events while generating the structure for them. Otherwise we would read
     # garbage (the internal full_sequence) when accessing normal event fields
     # there.
+    force_packed = False
     if hasattr(self, 'is_ge_event') and self.is_ge_event and self.name == name:
         event_size = 0
         for field in self.fields:
     if hasattr(self, 'is_ge_event') and self.is_ge_event and self.name == name:
         event_size = 0
         for field in self.fields:
@@ -2911,6 +2946,11 @@ def c_event(self, name):
                 full_sequence = Field(tcard32, tcard32.name, 'full_sequence', False, True, True)
                 idx = self.fields.index(field)
                 self.fields.insert(idx + 1, full_sequence)
                 full_sequence = Field(tcard32, tcard32.name, 'full_sequence', False, True, True)
                 idx = self.fields.index(field)
                 self.fields.insert(idx + 1, full_sequence)
+
+                # If the event contains any 64-bit extended fields, they need
+                # to remain aligned on a 64-bit boundary.  Adding full_sequence
+                # would normally break that; force the struct to be packed.
+                force_packed = any(f.type.size == 8 and f.type.is_simple for f in self.fields[(idx+1):])
                 break
 
     _c_type_setup(self, name, ('event',))
                 break
 
     _c_type_setup(self, name, ('event',))
@@ -2920,7 +2960,7 @@ def c_event(self, name):
 
     if self.name == name:
         # Structure definition
 
     if self.name == name:
         # Structure definition
-        _c_complex(self)
+        _c_complex(self, force_packed)
     else:
         # Typedef
         _h('')
     else:
         # Typedef
         _h('')
@@ -2964,13 +3004,19 @@ output = {'open'    : c_open,
 
 # Check for the argument that specifies path to the xcbgen python package.
 try:
 
 # Check for the argument that specifies path to the xcbgen python package.
 try:
-    opts, args = getopt.getopt(sys.argv[1:], 'p:m')
+    opts, args = getopt.getopt(sys.argv[1:], 'c:l:s:p:m')
 except getopt.GetoptError as err:
     print(err)
 except getopt.GetoptError as err:
     print(err)
-    print('Usage: c_client.py [-p path] file.xml')
+    print('Usage: c_client.py -c center_footer -l left_footer -s section [-p path] file.xml')
     sys.exit(1)
 
 for (opt, arg) in opts:
     sys.exit(1)
 
 for (opt, arg) in opts:
+    if opt == '-c':
+        center_footer=arg
+    if opt == '-l':
+        left_footer=arg
+    if opt == '-s':
+        section=arg
     if opt == '-p':
         sys.path.insert(1, arg)
     elif opt == '-m':
     if opt == '-p':
         sys.path.insert(1, arg)
     elif opt == '-m':
@@ -2998,8 +3044,6 @@ except OSError as e:
     if e.errno != errno.EEXIST:
         raise
 
     if e.errno != errno.EEXIST:
         raise
 
-today = time.strftime('%Y-%m-%d', time.gmtime(os.path.getmtime(args[0])))
-
 # Parse the xml header
 module = Module(args[0], output)
 
 # Parse the xml header
 module = Module(args[0], output)