[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