[Xcb] [PATCH proto 2/3] xcbgen-parser: support switch-case
Christian Linhart
chris at demorecorder.com
Tue Aug 19 06:55:33 PDT 2014
"case" is implemented as a variation of "bitcase" as follows:
The old class "BitCaseType" became the abstract class
"CaseOrBitcaseType" with two derived classes
"CaseType" and "BitcaseType".
(Therefore BitcaseType keeps the old semantic which may
be important for some generators)
There are two additional flags in class Type:
* is_case
* is_case_or_bitcase
The latter is for convenience because case and bitcase
have to be treated the same way in many cases.
The list of cases and bitcases in a SwitchType object
is still called "bitcases".
Reasons:
* Renaming that list would break generators based on the parser.
* Creating an extra list for cases would make other code more
complicated because you usually want to iterate over all
case and bitcase members of a switch.
---
xcbgen/expr.py | 2 +-
xcbgen/xtypes.py | 35 +++++++++++++++++++++++++++++------
2 files changed, 30 insertions(+), 7 deletions(-)
diff --git a/xcbgen/expr.py b/xcbgen/expr.py
index f9d5179..e4fb06e 100644
--- a/xcbgen/expr.py
+++ b/xcbgen/expr.py
@@ -116,15 +116,15 @@ class Expression(object):
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_bitcase:
+ 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
diff --git a/xcbgen/xtypes.py b/xcbgen/xtypes.py
index 3cd9032..45d7568 100644
--- a/xcbgen/xtypes.py
+++ b/xcbgen/xtypes.py
@@ -29,15 +29,17 @@ class Type(object):
self.is_list = False
self.is_expr = False
self.is_container = False
self.is_reply = False
self.is_union = False
self.is_pad = False
self.is_switch = False
+ self.is_case_or_bitcase = False
self.is_bitcase = False
+ self.is_case = False
def resolve(self, module):
'''
Abstract method for resolving a type.
This should make sure any referenced types are already declared.
'''
raise Exception('abstract resolve method not overridden!')
@@ -401,24 +403,28 @@ class SwitchType(ComplexType):
if self.resolved:
return
parents = list(self.parents) + [self]
# Resolve all of our field datatypes.
for index, child in enumerate(list(self.elt)):
- if child.tag == 'bitcase':
+ if child.tag == 'bitcase' or child.tag == 'case':
field_name = child.get('name')
if field_name is None:
- field_type = self.name + ('bitcase%d' % index,)
+ field_type = self.name + ('%s%d' % ( child.tag, index ),)
else:
field_type = self.name + (field_name,)
# use self.parent to indicate anchestor,
# as switch does not contain named fields itself
- type = BitcaseType(index, field_type, child, *parents)
+ if child.tag == 'bitcase':
+ type = BitcaseType(index, field_type, child, *parents)
+ else:
+ type = CaseType(index, field_type, child, *parents)
+
# construct the switch type name from the parent type and the field name
if field_name is None:
type.has_name = False
# Get the full type name for the field
field_type = type.name
visible = True
@@ -493,17 +499,17 @@ class Union(ComplexType):
def __init__(self, name, elt):
ComplexType.__init__(self, name, elt)
self.is_union = True
out = __main__.output['union']
-class BitcaseType(ComplexType):
+class CaseOrBitcaseType(ComplexType):
'''
- Derived class representing a struct data type.
+ Derived class representing a case or bitcase.
'''
def __init__(self, index, name, elt, *parent):
elts = list(elt)
self.expr = []
fields = []
for elt in elts:
if elt.tag == 'enumref':
@@ -511,15 +517,15 @@ class BitcaseType(ComplexType):
else:
fields.append(elt)
ComplexType.__init__(self, name, fields)
self.has_name = True
self.index = 1
self.lenfield_parent = list(parent) + [self]
self.parents = list(parent)
- self.is_bitcase = True
+ self.is_case_or_bitcase = True
def make_member_of(self, module, switch_type, field_type, field_name, visible, wire, auto, enum=None):
'''
register BitcaseType with the corresponding SwitchType
module is the global module object.
complex_type is the structure object.
@@ -542,14 +548,31 @@ class BitcaseType(ComplexType):
for e in self.expr:
e.resolve(module, self.parents+[self])
# Resolve the bitcase expression
ComplexType.resolve(self, module)
+class BitcaseType(CaseOrBitcaseType):
+ '''
+ Derived class representing a bitcase.
+ '''
+ def __init__(self, index, name, elt, *parent):
+ CaseOrBitcaseType.__init__(self, index, name, elt, *parent)
+ self.is_bitcase = True
+
+class CaseType(CaseOrBitcaseType):
+ '''
+ Derived class representing a case.
+ '''
+ def __init__(self, index, name, elt, *parent):
+ CaseOrBitcaseType.__init__(self, index, name, elt, *parent)
+ self.is_case = True
+
+
class Reply(ComplexType):
'''
Derived class representing a reply. Only found as a field of Request.
'''
def __init__(self, name, elt):
ComplexType.__init__(self, name, elt)
self.is_reply = True
--
2.0.1
More information about the Xcb
mailing list