xcb-doc: add paramref
[free-sw/xcb/proto] / xcbgen / expr.py
index ddfb76c..e6895ff 100644 (file)
@@ -11,14 +11,18 @@ class Field(object):
     visible is true iff the field should be in the request API.
     wire is true iff the field should be in the request structure.
     auto is true iff the field is on the wire but not in the request API (e.g. opcode)
+    enum is the enum name this field refers to, if any.
     '''
-    def __init__(self, type, field_type, field_name, visible, wire, auto):
+    def __init__(self, type, field_type, field_name, visible, wire, auto, enum=None, isfd=False):
         self.type = type
         self.field_type = field_type
         self.field_name = field_name
+        self.enum = enum
         self.visible = visible
         self.wire = wire
         self.auto = auto
+        self.isfd = isfd
+        self.parent = None
 
 
 class Expression(object):
@@ -49,6 +53,8 @@ class Expression(object):
         self.lhs = None
         self.rhs = None
 
+        self.contains_listelement_ref = False
+
         if elt.tag == 'list':
             # List going into a request, which has no length field (inferred by server)
             self.lenfield_name = elt.get('name') + '_len'
@@ -58,6 +64,10 @@ class Expression(object):
             # Standard list with a fieldref
             self.lenfield_name = elt.text
 
+        elif elt.tag == 'paramref':
+            self.lenfield_name = elt.text
+            self.lenfield_type = elt.get('type')
+
         elif elt.tag == 'valueparam':
             # Value-mask.  The length bitmask is described by attributes.
             self.lenfield_name = elt.get('value-mask-name')
@@ -100,6 +110,17 @@ class Expression(object):
         elif elt.tag == 'sumof':
             self.op = 'sumof'
             self.lenfield_name = elt.get('ref')
+            subexpressions = list(elt)
+            if len(subexpressions) > 0:
+                # sumof with a nested expression which is to be evaluated
+                # for each list-element in the context of that list-element.
+                # sumof then returns the sum of the results of these evaluations
+                self.rhs = Expression(subexpressions[0], parent)
+
+        elif elt.tag == 'listelement-ref':
+            # current list element inside iterating expressions such as sumof
+            self.op = 'listelement-ref'
+            self.contains_listelement_ref = True
 
         else:
             # Notreached
@@ -108,6 +129,12 @@ class Expression(object):
     def fixed_size(self):
         return self.nmemb != None
 
+    def recursive_resolve_tasks(self, module, parents):
+        for subexpr in (self.lhs, self.rhs):
+            if subexpr != None:
+                subexpr.recursive_resolve_tasks(module, parents)
+                self.contains_listelement_ref |= subexpr.contains_listelement_ref
+
     def resolve(self, module, parents):
         if self.op == 'enumref':
             self.lenfield_type = module.get_type(self.lenfield_name[0])
@@ -117,7 +144,13 @@ class Expression(object):
             for p in reversed(parents): 
                 fields = dict([(f.field_name, f) for f in p.fields])
                 if self.lenfield_name in fields.keys():
-                    self.lenfield_parent = p
+                    if p.is_case_or_bitcase:
+                        # switch is the anchestor 
+                        self.lenfield_parent = p.parents[-1]
+                    else:
+                        self.lenfield_parent = p
                     self.lenfield_type = fields[self.lenfield_name].field_type
                     break
+
+        self.recursive_resolve_tasks(module, parents)