[Spice-devel] [PATCH v3 40/51] Handle flags

Christophe Fergeau cfergeau at redhat.com
Thu Jul 23 06:39:17 PDT 2015


On Tue, Jul 21, 2015 at 05:46:10PM +0100, Frediano Ziglio wrote:
> Instead of only show the hexadecimal value show all bits.

'Instead of only showing the hexadecimal value, show all bits'
It might also be worth being more explicit what you mean by 'show all
bits'? The symbolic flag value rather than an int?

Christophe

> 
> Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
> ---
>  codegen/Makefile.am         |   1 +
>  codegen/check_dissector     |   3 ++
>  codegen/dissector_test.c    |  22 +++++++++
>  codegen/out_base1.txt       |  81 +++++++++++++++++++++++++++++----
>  codegen/out_flags1.txt      | 107 ++++++++++++++++++++++++++++++++++++++++++++
>  codegen/test.proto          |  10 +++++
>  python_modules/dissector.py |  92 ++++++++++++++++++++++++++++++++++---
>  7 files changed, 300 insertions(+), 16 deletions(-)
>  create mode 100644 codegen/out_flags1.txt
> 
> diff --git a/codegen/Makefile.am b/codegen/Makefile.am
> index 9e02d87..15e277e 100644
> --- a/codegen/Makefile.am
> +++ b/codegen/Makefile.am
> @@ -65,6 +65,7 @@ EXTRA_DIST =				\
>  	out_array_raw.txt		\
>  	out_array_struct.txt		\
>  	out_channel.txt			\
> +	out_flags1.txt			\
>  	$(NULL)
>  
>  CLEANFILES = test.c test.h enums.h dissector.c dissector.h *.trs check_dissector.txt
> diff --git a/codegen/check_dissector b/codegen/check_dissector
> index e2d06b5..94ce0bc 100755
> --- a/codegen/check_dissector
> +++ b/codegen/check_dissector
> @@ -62,4 +62,7 @@ check data_u16s 1 102 out_array_struct.txt --client
>  
>  check data_base1 1 2 out_channel.txt
>  
> +# flags and descriptions
> +check data_base1 1 3 out_flags1.txt
> +
>  exit 0
> diff --git a/codegen/dissector_test.c b/codegen/dissector_test.c
> index dcc0134..96b3107 100644
> --- a/codegen/dissector_test.c
> +++ b/codegen/dissector_test.c
> @@ -254,6 +254,28 @@ expert_add_info_format(packet_info *pinfo, proto_item *pi, expert_field *eiindex
>  		return;
>  }
>  
> +WS_DLL_PUBLIC proto_tree* proto_item_add_subtree(proto_item *ti, const gint idx)
> +{
> +	proto_tree *res;
> +
> +	assert(idx >= first_tree_registered);
> +	assert(idx <= last_tree_registered);
> +	if (!ti)
> +		return NULL;
> +
> +	assert(ti->tree_data == NULL);
> +	assert(ti->first_child == NULL);
> +	assert(ti->last_child == NULL);
> +	res = calloc(1, sizeof(*res));
> +	assert(res);
> +	res->tree_data = (void *) res;
> +	ti->first_child = res;
> +	ti->last_child = res;
> +	check_tree(res);
> +	check_item(ti);
> +	return res;
> +}
> +
>  struct all_ti
>  {
>  	proto_item ti;
> diff --git a/codegen/out_base1.txt b/codegen/out_base1.txt
> index 7921afd..66b42bc 100644
> --- a/codegen/out_base1.txt
> +++ b/codegen/out_base1.txt
> @@ -66,20 +66,83 @@
>      Type: FT_UINT32
>      Base: BASE_DEC
>      --- item
> -    Text: H (1)
> -    Name: f8
> -    Abbrev: spice2.auto.msg_base_Base1_f8
> +    Text: 1 (0x1)
> +    Name: F8
> +    Abbrev: spice2.f8_flags
>      Type: FT_UINT8
>      Base: BASE_HEX
> +        --- tree
> +            --- item
> +            Text: Not set
> +            Name: K
> +            Abbrev: spice2.F8_k
> +            Type: FT_BOOLEAN
> +            Base: 4
> +            --- item
> +            Text: Not set
> +            Name: J
> +            Abbrev: spice2.F8_j
> +            Type: FT_BOOLEAN
> +            Base: 4
> +            --- item
> +            Text: Not set
> +            Name: I
> +            Abbrev: spice2.F8_i
> +            Type: FT_BOOLEAN
> +            Base: 4
> +            --- item
> +            Text: Set
> +            Name: H
> +            Abbrev: spice2.F8_h
> +            Type: FT_BOOLEAN
> +            Base: 4
>      --- item
> -    Text: L (1)
> -    Name: f16
> -    Abbrev: spice2.auto.msg_base_Base1_f16
> +    Text: 1 (0x1)
> +    Name: F16
> +    Abbrev: spice2.f16_flags
>      Type: FT_UINT16
>      Base: BASE_HEX
> +        --- tree
> +            --- item
> +            Text: Not set
> +            Name: M
> +            Abbrev: spice2.F16_m
> +            Type: FT_BOOLEAN
> +            Base: 2
> +            --- item
> +            Text: Set
> +            Name: L
> +            Abbrev: spice2.F16_l
> +            Type: FT_BOOLEAN
> +            Base: 2
>      --- item
> -    Text: N (1)
> -    Name: f32
> -    Abbrev: spice2.auto.msg_base_Base1_f32
> +    Text: 1 (0x1)
> +    Name: F32
> +    Abbrev: spice2.f32_flags
>      Type: FT_UINT32
>      Base: BASE_HEX
> +        --- tree
> +            --- item
> +            Text: Not set
> +            Name: Q
> +            Abbrev: spice2.F32_q
> +            Type: FT_BOOLEAN
> +            Base: 4
> +            --- item
> +            Text: Not set
> +            Name: P
> +            Abbrev: spice2.F32_p
> +            Type: FT_BOOLEAN
> +            Base: 4
> +            --- item
> +            Text: Not set
> +            Name: O
> +            Abbrev: spice2.F32_o
> +            Type: FT_BOOLEAN
> +            Base: 4
> +            --- item
> +            Text: Set
> +            Name: N
> +            Abbrev: spice2.F32_n
> +            Type: FT_BOOLEAN
> +            Base: 4
> diff --git a/codegen/out_flags1.txt b/codegen/out_flags1.txt
> new file mode 100644
> index 0000000..0776300
> --- /dev/null
> +++ b/codegen/out_flags1.txt
> @@ -0,0 +1,107 @@
> +--- tree
> +    --- item
> +    Text: 130 (0x82)
> +    Name: Test flags
> +    Abbrev: spice2.tests_flag
> +    Type: FT_UINT8
> +    Base: BASE_DEC_HEX
> +        --- tree
> +            --- item
> +            Text: Not set
> +            Name: Z
> +            Abbrev: spice2.test_flags_z
> +            Type: FT_BOOLEAN
> +            Base: 3
> +            --- item
> +            Text: Set
> +            Name: Y
> +            Abbrev: spice2.test_flags_y
> +            Type: FT_BOOLEAN
> +            Base: 3
> +            --- item
> +            Text: Not set
> +            Name: X
> +            Abbrev: spice2.test_flags_x
> +            Type: FT_BOOLEAN
> +            Base: 3
> +    --- item
> +    Text: 129 (0x81)
> +    Name: Test flags override
> +    Abbrev: spice2.tests_flag_override
> +    Type: FT_UINT8
> +    Base: BASE_HEX_DEC
> +        --- tree
> +            --- item
> +            Text: Not set
> +            Name: Z
> +            Abbrev: spice2.test_flags_z
> +            Type: FT_BOOLEAN
> +            Base: 3
> +            --- item
> +            Text: Not set
> +            Name: Y
> +            Abbrev: spice2.test_flags_y
> +            Type: FT_BOOLEAN
> +            Base: 3
> +            --- item
> +            Text: Set
> +            Name: X
> +            Abbrev: spice2.test_flags_x
> +            Type: FT_BOOLEAN
> +            Base: 3
> +    --- item
> +    Text: 1 (0x1)
> +    Name: Test flags
> +    Abbrev: spice2.tests_flag
> +    Type: FT_UINT8
> +    Base: BASE_HEX_DEC
> +        --- tree
> +            --- item
> +            Text: Not set
> +            Name: Z
> +            Abbrev: spice2.test_flags_z
> +            Type: FT_BOOLEAN
> +            Base: 3
> +            --- item
> +            Text: Not set
> +            Name: Y
> +            Abbrev: spice2.test_flags_y
> +            Type: FT_BOOLEAN
> +            Base: 3
> +            --- item
> +            Text: Set
> +            Name: X
> +            Abbrev: spice2.test_flags_x
> +            Type: FT_BOOLEAN
> +            Base: 3
> +    --- item
> +    Text: 131 (0x83)
> +    Name: flags4
> +    Abbrev: spice2.auto.msg_base_Flags1_flags4
> +    Type: FT_UINT8
> +    Base: BASE_HEX_DEC
> +        --- tree
> +            --- item
> +            Text: Not set
> +            Name: K
> +            Abbrev: spice2.F8_k
> +            Type: FT_BOOLEAN
> +            Base: 4
> +            --- item
> +            Text: Not set
> +            Name: J
> +            Abbrev: spice2.F8_j
> +            Type: FT_BOOLEAN
> +            Base: 4
> +            --- item
> +            Text: Set
> +            Name: I
> +            Abbrev: spice2.F8_i
> +            Type: FT_BOOLEAN
> +            Base: 4
> +            --- item
> +            Text: Set
> +            Name: H
> +            Abbrev: spice2.F8_h
> +            Type: FT_BOOLEAN
> +            Base: 4
> diff --git a/codegen/test.proto b/codegen/test.proto
> index 0f14125..6d97317 100644
> --- a/codegen/test.proto
> +++ b/codegen/test.proto
> @@ -30,6 +30,10 @@ flags32 F32 {
>  	N, O, P, Q
>  };
>  
> +flags8 test_flags {
> +    X, Y, Z
> +} @ws("Test flags", tests_flag) @ws_base(DEC_HEX);
> +
>  struct Dummy {
>      uint16 dummy;
>  };
> @@ -67,6 +71,12 @@ channel BaseChannel {
>      message {
>          uint8 channel @ws_type(CHANNEL);
>      } Channel;
> +    message {
> +        test_flags flags1;
> +        test_flags flags2 @ws("Test flags override", tests_flag_override) @ws_base(HEX_DEC);
> +        test_flags flags3 @ws_base(HEX_DEC);
> +        F8 flags4 @ws_base(HEX_DEC);
> +    } Flags1;
>      Empty empty = 100;
>  
>    client:
> diff --git a/python_modules/dissector.py b/python_modules/dissector.py
> index 554f59c..84fbddb 100644
> --- a/python_modules/dissector.py
> +++ b/python_modules/dissector.py
> @@ -290,7 +290,7 @@ def get_primitive_ft_type(t):
>      return "FT_%sINT%d" % (unsigned, size * 8)
>  
>  # write a field
> -def write_wireshark_field(writer, container, member, t, ws, tree, size, encoding='ENC_LITTLE_ENDIAN', prefix=''):
> +def write_wireshark_field(writer, container, member, t, ws, tree, dest, size, encoding='ENC_LITTLE_ENDIAN', prefix=''):
>  
>      assert(member and container)
>  
> @@ -306,10 +306,15 @@ def write_wireshark_field(writer, container, member, t, ws, tree, size, encoding
>          f_type = get_primitive_ft_type(t)
>          size_name = str(t.get_fixed_nw_size() * 8)
>          if isinstance(t, ptypes.FlagsType):
> -            # show flag as hexadecimal for now
> -            base = 'BASE_HEX'
> -            assert(t.has_name())
> -            vals = 'VALS(%s_vs)' % codegen.prefix_underscore_lower(t.name)
> +            # if the attribute unique_flag is not set must compute
> +            # all flags writing a HF for each bit
> +            if t.has_attr('unique_flag'):
> +                base = 'BASE_HEX'
> +                assert(t.has_name())
> +                vals = 'VALS(%s_vs)' % codegen.prefix_underscore_lower(t.name)
> +            else:
> +                write_flags(writer, container, member, t, ws, tree, dest)
> +                return
>          elif isinstance(t, ptypes.EnumType) or isinstance(t, ptypes.EnumBaseType):
>              base = 'BASE_DEC'
>              assert(t.has_name())
> @@ -449,7 +454,7 @@ def write_array(writer, container, member, nelements, array, dest, scope):
>      element_type = array.element_type
>  
>      if element_type == ptypes.uint8 or element_type == ptypes.int8:
> -        write_wireshark_field(writer, container, member, array, ws, dest.level.tree, nelements, 'ENC_NA')
> +        write_wireshark_field(writer, container, member, array, ws, dest.level.tree, dest, nelements, 'ENC_NA')
>          writer.increment("offset", nelements)
>          return
>  
> @@ -539,13 +544,86 @@ def write_struct(writer, member, t, index, dest, scope):
>          write_struct_func(writer, t, func_name, index)
>          writer.assign('offset', '%s(glb, %s, offset, %s)' % (func_name, dest.level.tree, index))
>  
> +
> +def write_flags_func(writer, t, ws, tree, ti):
> +    size = t.get_fixed_nw_size()
> +    hf_name = 'hf_%s_flag%d' % (t.name, size*8)
> +    func_name = 'dissect_flags%d_%s' % (size*8, t.name)
> +    stmt = '%s(glb, %s, offset, %s)' % (func_name, tree, ti)
> +
> +    if writer.is_generated("flags", t.name):
> +        return stmt
> +    writer.set_is_generated("flags", t.name)
> +
> +    writer = writer.function_helper()
> +    scope = writer.function(func_name, "proto_item *", "GlobalInfo *glb _U_, proto_tree *tree _U_, guint32 offset, proto_item *ti", True)
> +    dest = RootDestination(scope)
> +
> +    desc = ws.desc if ws.desc else t.name
> +    hf = HF(hf_name, desc)
> +    hf.ws_name = ws.name if ws.name else '%s_flags' % (t.name.lower())
> +    hf.f_type = get_primitive_ft_type(t)
> +    hf.base = 'BASE_%s' % (ws.base if ws.base else 'HEX')
> +    hf.vals = 'NULL'
> +    hf.create()
> +
> +    with writer.if_block('ti == NULL'):
> +        writer.assign('ti', 'proto_tree_add_item(tree, %s, glb->tvb, offset, %d, ENC_LITTLE_ENDIAN)' % (hf_name, size))
> +    writer.assign('tree', 'proto_item_add_subtree(ti, %s)' % new_ett(writer))
> +
> +    values = list(t.names.keys())
> +    values.sort()
> +    values.reverse()
> +    bits = max(values) + 1
> +    for v in values:
> +        name = hf_name + '_' + t.names[v].lower()
> +
> +        desc = t.descs[v] if t.descs[v] else t.names[v]
> +        hf = HF(name, desc)
> +        hf.ws_name = '%s_%s' % (t.name, t.names[v].lower())
> +        hf.f_type = 'FT_BOOLEAN'
> +        hf.base = str(bits)
> +        hf.vals = 'TFS(&tfs_set_notset)'
> +        hf.mask = t.c_enumname(v)
> +        hf.create()
> +
> +        writer.statement('proto_tree_add_item(tree, %s, glb->tvb, offset, %d, ENC_LITTLE_ENDIAN)' % (name, size))
> +
> +    writer.statement('return ti');
> +    writer.end_block()
> +
> +    return stmt
> +
> +
> +def write_flags(writer, container, member, t, ws, tree, dest):
> +    if ws.type:
> +        assert False, "Attribute ws_type for member %s flag %s are ignored" % (member.name, t.name)
> +
> +    ws_func = WSAttributes(t)
> +
> +    own_ti = ws.name != ws_func.name or ws.desc != ws_func.desc or ws.base != ws_func.base
> +    if not own_ti:
> +        stmt = write_flags_func(writer, t, ws_func, tree, 'NULL')
> +        writer.statement(stmt)
> +        return
> +
> +    tree = dest.level.tree
> +    with writer.block() as scope, dest.level:
> +        scope.variable_def('proto_item *', dest.level.ti)
> +        size = t.get_fixed_nw_size()
> +        int_type = ptypes.IntegerType(size*8, False)
> +        write_wireshark_field(writer, container, member, int_type, ws, tree, dest, size, prefix=dest.level.ti + ' = ')
> +        stmt = write_flags_func(writer, t, ws_func, tree, dest.level.ti)
> +        writer.statement(stmt)
> +
> +
>  def write_member_primitive(writer, container, member, t, ws, dest, scope):
>      assert(t.is_primitive())
>  
>      if member.has_attr("bytes_count"):
>          raise NotImplementedError("bytes_count not implemented")
>  
> -    write_wireshark_field(writer, container, member, t, ws, dest.level.tree, t.get_fixed_nw_size())
> +    write_wireshark_field(writer, container, member, t, ws, dest.level.tree, dest, t.get_fixed_nw_size())
>      if member.has_attr("bytes_count"):
>          dest_var = member.attributes["bytes_count"][0]
>      else:
> -- 
> 2.1.0
> 
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/spice-devel/attachments/20150723/dc0d0477/attachment-0001.sig>


More information about the Spice-devel mailing list