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

Submitted by Frediano Ziglio on July 21, 2015, 4:46 p.m.

Details

Message ID 1437497181-26929-41-git-send-email-fziglio@redhat.com
State New
Headers show

Not browsing as part of any series.

Commit Message

Frediano Ziglio July 21, 2015, 4:46 p.m.
Instead of only show the hexadecimal value show all bits.

Signed-off-by: Frediano Ziglio <fziglio@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

Patch hide | download patch | download mbox

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:

Comments

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@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@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel