[libxcb,1/1] Calculate length of lengthless lists

Submitted by Jaya Tiwari on March 9, 2015, 6:43 a.m.

Details

Message ID CAGt7qzVHWseNiHuy=Nq1C=TA6v1YH+temSNAgJUZq-VPOwMLpg@mail.gmail.com
State New
Headers show

Not browsing as part of any series.

Commit Message

Jaya Tiwari March 9, 2015, 6:43 a.m.
The lengthless lists that are the only variable part of the request
with all other fixed part
declared above it are identified from the previous passes and have
length calculated as
( length*4 - total_size_of_fixed_size_fields ) / size_of_listmember

Signed-off-by: Jaya Tiwari <tiwari.jaya18@gmail.com>
---
 src/c_client.py | 54 +++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 41 insertions(+), 13 deletions(-)

             # the field should appear as a parameter in the function call
@@ -779,6 +780,8 @@ def get_serialize_params(context, self,
buffer_var='_buffer', aux_var='_aux'):
     if self.is_switch:
         param_fields = get_expr_fields(self)

+    if self.is_list and self.type.expr.op == 'calculate_len':
+ dont_include_len = True
     # _serialize()/_unserialize()/_unpack() function parameters
     # note: don't use set() for params, it is unsorted
     params = []
@@ -802,7 +805,7 @@ def get_serialize_params(context, self,
buffer_var='_buffer', aux_var='_aux'):
             pointerspec = p.c_pointer
             add_param(params, (typespec, pointerspec, p.c_field_name))
         else:
-            if p.visible and not p.wire and not p.auto:
+            if p.visible and not p.wire and not p.auto and not
dont_include_len:
                 typespec = p.c_field_type
                 pointerspec = ''
                 add_param(params, (typespec, pointerspec, p.c_field_name))
@@ -998,7 +1001,10 @@ def _c_serialize_helper_list_field(context, self, field,
         if len(unresolved)>0:
             raise Exception('could not resolve the length fields
required for list %s' % field.c_field_name)

-    list_length = _c_accessor_get_expr(expr, field_mapping)
+    if expr.op == 'calculate_len':
+ list_length = field.type.expr.lenfield_name
+    else:
+        list_length = _c_accessor_get_expr(expr, field_mapping)

     # default: list with fixed size elements
     length = '%s * sizeof(%s)' % (list_length, field.type.member.c_wiretype)
@@ -1742,7 +1748,7 @@ def _c_accessor_get_expr(expr, field_mapping):
         return sumvar
     elif expr.op == 'listelement-ref':
         return '(*xcb_listelement)'
-    elif expr.op != None:
+    elif expr.op != None and expr.op != 'calculate_len':
         return ('(' + _c_accessor_get_expr(expr.lhs, field_mapping) +
                 ' ' + expr.op + ' ' +
                 _c_accessor_get_expr(expr.rhs, field_mapping) + ')')
@@ -1824,6 +1830,7 @@ def _c_accessors_list(self, field):

     list = field.type
     c_type = self.c_type
+    dont_need_len = False

     # special case: switch
     # in case of switch, 2 params have to be supplied to certain
accessor functions:
@@ -1925,16 +1932,25 @@ def _c_accessors_list(self, field):
     _hc('')
     _hc('int')
     spacing = ' '*(len(field.c_length_name)+2)
-    add_param_str = additional_params_to_str(spacing)
+    if field.type.is_list and field.type.expr.op == 'calculate_len':
+ dont_need_len = True
+    else:
+        add_param_str = additional_params_to_str(spacing)
     if switch_obj is not None:
         _hc('%s (const %s *R  /**< */,', field.c_length_name, R_obj.c_type)
         _h('%sconst %s *S /**< */%s);', spacing, S_obj.c_type, add_param_str)
         _c('%sconst %s *S  /**< */%s)', spacing, S_obj.c_type, add_param_str)
-    else:
+    elif not dont_need_len:
         _h('%s (const %s *R  /**< */%s);', field.c_length_name,
c_type, add_param_str)
         _c('%s (const %s *R  /**< */%s)', field.c_length_name,
c_type, add_param_str)
+    else:
+ _h('%s (const %s *R  /**< */);', field.c_length_name, c_type)
+        _c('%s (const %s *R  /**< */)', field.c_length_name, c_type)
     _c('{')
-    length = _c_accessor_get_expr(field.type.expr, fields)
+    if field.type.expr.op == 'calculate_len':
+ length = '(((R->length * 4) - sizeof('+ self.c_type +
'))/'+'sizeof('+field.type.member.c_wiretype+'))'
+    else:
+        length = _c_accessor_get_expr(field.type.expr, fields)
     _c('    return %s;', length)
     _c('}')

@@ -1975,19 +1991,26 @@ def _c_accessors_list(self, field):
         _hc('')
         _hc('%s', field.c_iterator_type)
         spacing = ' '*(len(field.c_iterator_name)+2)
-        add_param_str = additional_params_to_str(spacing)
+ if field.type.expr.op != 'calculate_len':
+            add_param_str = additional_params_to_str(spacing)
         if switch_obj is not None:
             _hc('%s (const %s *R  /**< */,', field.c_iterator_name,
R_obj.c_type)
             _h('%sconst %s *S /**< */%s);', spacing, S_obj.c_type,
add_param_str)
             _c('%sconst %s *S  /**< */%s)', spacing, S_obj.c_type,
add_param_str)
-        else:
+        elif not dont_need_len:
             _h('%s (const %s *R  /**< */%s);', field.c_iterator_name,
c_type, add_param_str)
             _c('%s (const %s *R  /**< */%s)', field.c_iterator_name,
c_type, add_param_str)
+ else:
+    _h('%s (const %s *R  /**< */);', field.c_iterator_name, c_type)
+            _c('%s (const %s *R  /**< */)', field.c_iterator_name, c_type)
         _c('{')
         _c('    %s i;', field.c_iterator_type)

         _c_pre.start()
-        length_expr_str = _c_accessor_get_expr(field.type.expr, fields)
+ if field.type.expr.op == 'calculate_len':
+            length_expr_str = '(((R->length * 4) - sizeof('+
self.c_type + '))/'+'sizeof('+field.c_field_type+'))'
+ else:
+            length_expr_str = _c_accessor_get_expr(field.type.expr, fields)

         if switch_obj is not None:
             _c_pre.end()
@@ -2181,6 +2204,7 @@ def _c_request_helper(self, name, cookie_type,
void, regular, aux=False, reply_f
     serial_fields = []
     # special case: list with variable size elements
     list_with_var_size_elems = False
+    have_field_len = False

     for field in self.fields:
         if field.visible:
@@ -2373,9 +2397,13 @@ def _c_request_helper(self, name, cookie_type,
void, regular, aux=False, reply_f
                     _c('    xcb_parts[%d].iov_base = (char *) %s;',
count, field.c_field_name)
                     if field.type.is_list:
                         if field.type.member.fixed_size():
-                            _c('    xcb_parts[%d].iov_len = %s *
sizeof(%s);', count,
-                               _c_accessor_get_expr(field.type.expr, None),
-                               field.type.member.c_wiretype)
+    if field.type.expr.op == 'calculate_len':
+ lenfield = field.type.expr.lenfield_name
+    else:
+ lenfield = _c_accessor_get_expr(field.type.expr, None)
+
+                            _c('    xcb_parts[%d].iov_len = %s *
sizeof(%s);', count, lenfield,
+                                        field.type.member.c_wiretype)
                         else:
                             list_length =
_c_accessor_get_expr(field.type.expr, None)

Patch hide | download patch | download mbox

diff --git a/src/c_client.py b/src/c_client.py
index 8a2900c..684eb6a 100644
--- a/src/c_client.py
+++ b/src/c_client.py
@@ -654,7 +654,7 @@  def get_expr_fields(self):
     get the Fields referenced by switch or list expression
     """
     def get_expr_field_names(expr):
-        if expr.op is None:
+        if expr.op is None or expr.op == 'calculate_len':
             if expr.lenfield_name is not None:
                 return [expr.lenfield_name]
             else:
@@ -763,6 +763,7 @@  def get_serialize_params(context, self,
buffer_var='_buffer', aux_var='_aux'):
     param_fields = []
     wire_fields = []

+    dont_include_len = False
     for field in self.fields:
         if field.visible: