[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