Wireshark-dev: Re: [Wireshark-dev] proto_tree_add_item() with range_string

From: Sebastien Tandel <sebastien@xxxxxxxxx>
Date: Fri, 12 Jan 2007 20:46:30 +0100
Here is the patch to have a more precise idea of what has changed (and
if you want to try it :))  ... and the example of Jaap modified to work
with the patch provided :

static const range_string rs_value[] = {
    {  0, 49, "Little" },
    { 50, 99, "Some" },
    {100,199, "Considerable" },
    {200,255, "High" },
    {  0,  0, NULL }
  };
RVALS_INT(rs_value, rs_value_int)

  proto_tree_add_item(tree, hf_proto_value, tvb, offset, 1, FALSE);

  static hf_register_info hf[] = {
    { &hf_proto_value,
      { "Value", "proto.value",
        FT_UINT8, BASE_DEC,
        RVALS(rs_value_int), 0x0,
        "How much is it worth", HFILL }}
  };


+ Frame
+ Ethernet II
+ IP
+ TCP
+ Proto
  Value: High (220)


ChangeLog :
- RVALS_INT(rs_value, rs_value_int) is added to encapsulate the
range_string structure
- and the macro RVALS take another input, to know rs_value_int


Regards,

Sebastien Tandel

Jaap Keuter wrote:
> Hi,
>
> My first impression is that the RS() macro (refer to code sample below)
> needs to be implemented to work with the range_string type. I've got
> really no idea what is involved with that.
>
> Thanx,
> Jaap
>
> On Fri, 12 Jan 2007, Anders Broman wrote:
>
>   
>> Hi,
>> I had a brief look some time ago and it looked
>> To me like it would require new FT_x:s or
>> That the macros VAL and TFS would have to be changed to supply
>> the needed functions. Is there a better way to do it?
>>
>> BR
>> Anders
>>
>> -----Ursprungligt meddelande-----
>> Frï¿œn: wireshark-dev-bounces@xxxxxxxxxxxxx
>> [mailto:wireshark-dev-bounces@xxxxxxxxxxxxx] Fï¿œr Jaap Keuter
>> Skickat: den 12 januari 2007 15:48
>> Till: Developer support list for Wireshark
>> ï¿œmne: Re: [Wireshark-dev] proto_tree_add_item() with range_string
>>
>> Hi,
>>
>> Yeah, that would be nice, having stuff like this:
>>
>>   static const range_string rs_value[] = {
>>     {  0, 49, "Little" },
>>     { 50, 99, "Some" },
>>     {100,199, "Considerable" },
>>     {200,255, "High" },
>>     {  0,  0, NULL }
>>   };
>>
>>   proto_tree_add_item(tree, hf_proto_value, tvb, offset, 1, FALSE);
>>
>>   static hf_register_info hf[] = {
>>     { &hf_proto_value,
>>       { "Value", "proto.value",
>>         FT_UINT8, BASE_DEC,
>>         RS(rs_value), 0x0,
>>         "How much is it worth", HFILL }}
>>   };
>>
>> + Frame
>> + Ethernet II
>> + IP
>> + TCP
>> + Proto
>>   Value: High (220)
>>
>> That would require weaving in the range string handling along the types
>> where VALS() and TFS() handling applies (FT_*INT*, and FT_BOOLEAN).
>> epan/proto.c comes to mind.
>>
>> Thanx,
>> Jaap
>>
>> On Fri, 12 Jan 2007, Anders Broman wrote:
>>
>>     
>>> Hi,
>>> Does some have an idea on how to implement proto_tree_add_item() with a
>>> range_string?
>>> That would be really useful.
>>> BR
>>> Anders
>>>
>>>
>>>       
>> _______________________________________________
>> Wireshark-dev mailing list
>> Wireshark-dev@xxxxxxxxxxxxx
>> http://www.wireshark.org/mailman/listinfo/wireshark-dev
>>
>> _______________________________________________
>> Wireshark-dev mailing list
>> Wireshark-dev@xxxxxxxxxxxxx
>> http://www.wireshark.org/mailman/listinfo/wireshark-dev
>>
>>
>>     
>
>   
> ------------------------------------------------------------------------
>
> _______________________________________________
> Wireshark-dev mailing list
> Wireshark-dev@xxxxxxxxxxxxx
> http://www.wireshark.org/mailman/listinfo/wireshark-dev
>   

Index: gtk/isis_analysis.c
===================================================================
Index: gtk/isis_analysis.h
===================================================================
Index: epan/value_string.h
===================================================================
--- epan/value_string.h	(r�vision 20409)
+++ epan/value_string.h	(copie de travail)
@@ -41,6 +41,15 @@
   const gchar   *strptr;
 } range_string;
 
+/* Structure used to encapsulate a range_string (maybe other in the future?)
+ * and able to be used inside a hf_register_info with RVALS macro. */
+typedef struct _int_rval_val {
+  guint32 value;
+  gchar * strptr;
+  const range_string * rstr;
+}int_rval_val;
+
+
 /* #define VS_DEF(x) { x, #x } */
 /* #define VS_END    { 0, NULL } */
 
Index: epan/proto.c
===================================================================
--- epan/proto.c	(r�vision 20409)
+++ epan/proto.c	(copie de travail)
@@ -4009,6 +4009,9 @@
 
 }
 
+#define INT_RVAL_GET_STR(x) ((const int_rval_val*)(x))->strptr
+#define RVAL_GET(x) ((const int_rval_val*)(x))->rstr
+
 static void
 fill_label_enumerated_uint(field_info *fi, gchar *label_str)
 {
@@ -4023,9 +4026,15 @@
 	value = fvalue_get_integer(&fi->value);
 
 	/* Fill in the textual info */
-	ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+	if (INT_RVAL_GET_STR(hfinfo->strings) == NULL) {
+	  ret = g_snprintf(label_str, ITEM_LABEL_LENGTH, 
 			format,  hfinfo->name,
+			rval_to_str(value, RVAL_GET(hfinfo->strings), "Unknown"), value);
+	} else {
+	  ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+			format,  hfinfo->name,
 			val_to_str(value, cVALS(hfinfo->strings), "Unknown"), value);
+	}
 	if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
 		label_str[ITEM_LABEL_LENGTH - 1] = '\0';
 }
@@ -4091,9 +4100,15 @@
 	value = fvalue_get_integer(&fi->value);
 
 	/* Fill in the textual info */
-	ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+	if (INT_RVAL_GET_STR(hfinfo->strings) == NULL) {
+	  ret = g_snprintf(label_str, ITEM_LABEL_LENGTH, 
 			format,  hfinfo->name,
+			rval_to_str(value, RVAL_GET(hfinfo->strings), "Unknown"), value);
+	} else {
+	  ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+			format,  hfinfo->name,
 			val_to_str(value, cVALS(hfinfo->strings), "Unknown"), value);
+	}
 	if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
 		label_str[ITEM_LABEL_LENGTH - 1] = '\0';
 }
Index: epan/proto.h
===================================================================
--- epan/proto.h	(r�vision 20409)
+++ epan/proto.h	(copie de travail)
@@ -65,6 +65,19 @@
 /** Make a const true_false_string[] look like a _true_false_string pointer, used to set header_field_info.strings */
 #define TFS(x)	(const struct true_false_string*)(x)
 
+/** Make a const value_string[] look like a _value_string pointer, used to set
+ * header_field_info.strings */
+#define RVALS(x) (const struct _value_string*)(x)
+
+/* we define another intermediate structure which is helping us in
+ * fill_label_enumerated_(u)int to determine that we're using a range_string
+ * structure 
+ * NOTE : This macro must be applied to the range_string variable we want use with RVALS(x) 
+ */
+#define RVALS_INT(rstr, int_rstr) const int_rval_val (int_rstr)[]= { \
+  { 0, NULL, (rstr) } \
+};
+
 struct _protocol;
 
 /** Structure for information about a protocol */