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):
self.lenfield_name = None
self.lenfield_type = None
+ self.lenfield_parent = None
self.lenfield = None
self.lenwire = False
self.bitfield = False
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'
# 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')
self.rhs = Expression(list(elt)[0], parent)
self.lenfield_name = self.rhs.lenfield_name
-
+
elif elt.tag == 'value':
# Constant expression
self.nmemb = int(elt.text, 0)
+ elif elt.tag == 'popcount':
+ self.op = 'popcount'
+ self.rhs = Expression(list(elt)[0], parent)
+ self.lenfield_name = self.rhs.lenfield_name
+ # xcb_popcount returns 'int' - handle the type in the language-specific part
+
+ elif elt.tag == 'enumref':
+ self.op = 'enumref'
+ self.lenfield_name = (elt.get('ref'), elt.text)
+
+ 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
- raise Exception('XXX')
-
+ raise Exception("undefined tag '%s'" % elt.tag)
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])
+ self.lenfield_name = self.lenfield_name[1]
+ elif self.op == 'sumof':
+ # need to find the field with lenfield_name
+ for p in reversed(parents):
+ fields = dict([(f.field_name, f) for f in p.fields])
+ if self.lenfield_name in fields.keys():
+ 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)
+