[Xcb] [PATCH proto 2/3] xcbgen-parser: support switch-case

Ran Benita ran234 at gmail.com
Sat Aug 23 08:50:30 PDT 2014


On Tue, Aug 19, 2014 at 03:55:33PM +0200, Christian Linhart wrote:
> "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.

Not sure what the API guarantees for xcbgen are, but assuming it needs
to be stable, this is

Reviewed-by: Ran Benita <ran234 at gmail.com>

I do wonder why xcbgen creates all of these is_* attributes, instead of
using "instanceof" or "type"...

Ran

> ---
>  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
> 
> _______________________________________________
> Xcb mailing list
> Xcb at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/xcb


More information about the Xcb mailing list