Rename proto_construct_dfilter_string() to
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 23 Nov 2006 21:16:46 +0000 (21:16 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 23 Nov 2006 21:16:46 +0000 (21:16 +0000)
proto_construct_match_selected_string() to indicate what it does - and
have it return a Boolean indication of whether the string could be
built, returning the string through a pointer, and, if that pointer is
null, have it just return the Boolean and not construct the string.

Get rid of proto_can_match_selected() -
proto_construct_match_selected_string() can be used for that, which
means we have only one piece of code that knows whether a "match
selected" string can be constructed or not.

Have proto_construct_match_selected_string() support matching
zero-length FT_NONE (and FT_PCRE, but that shouldn't happen) fields even
if there's no epan_dissect_t, as such a match just checks whether the
field is present.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@19967 f5534014-38df-0310-8fa8-9805f1628bb7

epan/proto.c
epan/proto.h
gtk/expert_comp_table.c
gtk/main.c
gtk/menu.c
print.c
tap-protocolinfo.c

index b6d2983acb149310ec1ea20801d5cf2c9187b201..9746c5476fee944b4463dda279282a1c9d77f300 100644 (file)
@@ -5070,86 +5070,21 @@ hfinfo_numeric_format(header_field_info *hfinfo)
        return format;
 }
 
-/*
- * Returns TRUE if we can do a "match selected" on the field, FALSE
- * otherwise.
- */
-gboolean
-proto_can_match_selected(field_info *finfo, epan_dissect_t *edt)
-{
-       header_field_info       *hfinfo;
-       gint                    length;
-
-       hfinfo = finfo->hfinfo;
-       DISSECTOR_ASSERT(hfinfo);
-
-       switch(hfinfo->type) {
-
-               case FT_NONE:
-               case FT_PCRE:
-                       /*
-                        * This doesn't have a value, so we'd match
-                        * on the raw bytes at this address.
-                        *
-                        * Should we be allowed to access to the raw bytes?
-                        * If "edt" is NULL, the answer is "no".
-                        */
-                       if (edt == NULL)
-                               return FALSE;
-
-                       /*
-                        * Is this field part of the raw frame tvbuff?
-                        * If not, we can't use "frame[N:M]" to match
-                        * it.
-                        *
-                        * XXX - should this be frame-relative, or
-                        * protocol-relative?
-                        *
-                        * XXX - does this fallback for non-registered
-                        * fields even make sense?
-                        */
-                       if (finfo->ds_tvb != edt->tvb)
-                               return FALSE;
-
-                       /*
-                        * If the length is 0, we will just match the name
-                        * of the field.
-                        *
-                        * (Also check for negative values, just in case,
-                        * as we'll cast it to an unsigned value later.)
-                        */
-                       length = finfo->length;
-                       if (length < 0)
-                               return FALSE;
-
-                       /*
-                        * Don't go past the end of that tvbuff.
-                        */
-                       if ((guint)length > tvb_length(finfo->ds_tvb))
-                               length = tvb_length(finfo->ds_tvb);
-                       if (length <= 0)
-                               return FALSE;
-                       return TRUE;
-
-               default:
-                       /*
-                        * By default, assume the type has a value, so
-                        * we can match.
-                        */
-                       return TRUE;
-       }
-}
-
-/* This function returns a string allocated with packet lifetime scope.
+/* This function indicates whether it's possible to construct a
+ * "match selected" display filter string for the specified field,
+ * returns an indication of whether it's possible, and, if it's
+ * possible and "filter" is non-null, constructs the filter and
+ * sets "*filter" to point to it.
  * You do not need to [g_]free() this string since it will be automatically
  * freed once the next packet is dissected.
  */
-char*
-proto_construct_dfilter_string(field_info *finfo, epan_dissect_t *edt)
+gboolean
+proto_construct_match_selected_string(field_info *finfo, epan_dissect_t *edt,
+    char **filter)
 {
        header_field_info       *hfinfo;
        int                     abbrev_len;
-       char                    *buf, *ptr;
+       char                    *ptr;
        int                     buf_len;
        const char              *format;
        int                     dfilter_len, i;
@@ -5207,10 +5142,14 @@ proto_construct_dfilter_string(field_info *finfo, epan_dissect_t *edt)
                         *
                         * 1 byte for the trailing '\0'.
                         */
-                       dfilter_len = abbrev_len + 4 + 11 + 1;
-                       buf = ep_alloc0(dfilter_len);
-                       format = hfinfo_numeric_format(hfinfo);
-                       g_snprintf(buf, dfilter_len, format, hfinfo->abbrev, fvalue_get_integer(&finfo->value));
+                       if (filter != NULL) {
+                               dfilter_len = abbrev_len + 4 + 11 + 1;
+                               *filter = ep_alloc0(dfilter_len);
+                               format = hfinfo_numeric_format(hfinfo);
+                               g_snprintf(*filter, dfilter_len, format,
+                                   hfinfo->abbrev,
+                                   fvalue_get_integer(&finfo->value));
+                       }
                        break;
 
                case FT_INT64:
@@ -5231,18 +5170,39 @@ proto_construct_dfilter_string(field_info *finfo, epan_dissect_t *edt)
                         *
                         * 1 byte for the trailing '\0'.
                         */
-                       dfilter_len = abbrev_len + 4 + 22 + 1;
-                       buf = ep_alloc0(dfilter_len);
-                       format = hfinfo_numeric_format(hfinfo);
-                       g_snprintf(buf, dfilter_len, format, hfinfo->abbrev, fvalue_get_integer64(&finfo->value));
+                       if (filter != NULL) {
+                               dfilter_len = abbrev_len + 4 + 22 + 1;
+                               *filter = ep_alloc0(dfilter_len);
+                               format = hfinfo_numeric_format(hfinfo);
+                               g_snprintf(*filter, dfilter_len, format,
+                                   hfinfo->abbrev,
+                                   fvalue_get_integer64(&finfo->value));
+                       }
                        break;
 
                case FT_PROTOCOL:
-                       buf = ep_strdup(finfo->hfinfo->abbrev);
+                       if (filter != NULL)
+                               *filter = ep_strdup(finfo->hfinfo->abbrev);
                        break;
 
                case FT_NONE:
                case FT_PCRE:
+                       /*
+                        * If the length is 0, just match the name of the
+                        * field.
+                        *
+                        * (Also check for negative values, just in case,
+                        * as we'll cast it to an unsigned value later.)
+                        */
+                       length = finfo->length;
+                       if (length == 0) {
+                               if (filter != NULL)
+                                       *filter = ep_strdup(finfo->hfinfo->abbrev);
+                               break;
+                       }
+                       if (length < 0)
+                               return FALSE;
+
                        /*
                         * This doesn't have a value, so we'd match
                         * on the raw bytes at this address.
@@ -5251,7 +5211,7 @@ proto_construct_dfilter_string(field_info *finfo, epan_dissect_t *edt)
                         * If "edt" is NULL, the answer is "no".
                         */
                        if (edt == NULL)
-                               return NULL;
+                               return FALSE;
 
                        /*
                         * Is this field part of the raw frame tvbuff?
@@ -5265,22 +5225,7 @@ proto_construct_dfilter_string(field_info *finfo, epan_dissect_t *edt)
                         * fields even make sense?
                         */
                        if (finfo->ds_tvb != edt->tvb)
-                               return NULL;    /* you lose */
-
-                       /*
-                        * If the length is 0, just match the name of the
-                        * field.
-                        *
-                        * (Also check for negative values, just in case,
-                        * as we'll cast it to an unsigned value later.)
-                        */
-                       length = finfo->length;
-                       if (length == 0) {
-                               buf = ep_strdup(finfo->hfinfo->abbrev);
-                               break;
-                       }
-                       if (length < 0)
-                               return NULL;
+                               return FALSE;   /* you lose */
 
                        /*
                         * Don't go past the end of that tvbuff.
@@ -5289,22 +5234,25 @@ proto_construct_dfilter_string(field_info *finfo, epan_dissect_t *edt)
                        if (length > length_remaining)
                                length = length_remaining;
                        if (length <= 0)
-                               return NULL;
-
-                       start = finfo->start;
-                       buf_len = 32 + length * 3;
-                       buf = ep_alloc0(buf_len);
-                       ptr = buf;
-
-                       ptr += g_snprintf(ptr, buf_len-(ptr-buf), "frame[%d:%d] == ", finfo->start, length);
-                       for (i=0;i<length; i++) {
-                               c = tvb_get_guint8(finfo->ds_tvb, start);
-                               start++;
-                               if (i == 0 ) {
-                                       ptr += g_snprintf(ptr, buf_len-(ptr-buf), "%02x", c);
-                               }
-                               else {
-                                       ptr += g_snprintf(ptr, buf_len-(ptr-buf), ":%02x", c);
+                               return FALSE;
+
+                       if (filter != NULL) {
+                               start = finfo->start;
+                               buf_len = 32 + length * 3;
+                               *filter = ep_alloc0(buf_len);
+                               ptr = *filter;
+
+                               ptr += g_snprintf(ptr, buf_len-(ptr-*filter),
+                                   "frame[%d:%d] == ", finfo->start, length);
+                               for (i=0;i<length; i++) {
+                                       c = tvb_get_guint8(finfo->ds_tvb, start);
+                                       start++;
+                                       if (i == 0 ) {
+                                               ptr += g_snprintf(ptr, buf_len-(ptr-*filter), "%02x", c);
+                                       }
+                                       else {
+                                               ptr += g_snprintf(ptr, buf_len-(ptr-*filter), ":%02x", c);
+                                       }
                                }
                        }
                        break;
@@ -5316,18 +5264,21 @@ proto_construct_dfilter_string(field_info *finfo, epan_dissect_t *edt)
                         *      4 bytes for " == ".
                         *      1 byte for trailing NUL.
                         */
-                       dfilter_len = fvalue_string_repr_len(&finfo->value,
-                                       FTREPR_DFILTER);
-                       dfilter_len += abbrev_len + 4 + 1;
-                       buf = ep_alloc0(dfilter_len);
-
-                       /* Create the string */
-                       g_snprintf(buf, dfilter_len, "%s == ", hfinfo->abbrev);
-                       fvalue_to_string_repr(&finfo->value,
-                                       FTREPR_DFILTER,
-                                       &buf[abbrev_len + 4]);
+                       if (filter != NULL) {
+                               dfilter_len = fvalue_string_repr_len(&finfo->value,
+                                               FTREPR_DFILTER);
+                               dfilter_len += abbrev_len + 4 + 1;
+                               *filter = ep_alloc0(dfilter_len);
+
+                               /* Create the string */
+                               g_snprintf(*filter, dfilter_len, "%s == ",
+                                   hfinfo->abbrev);
+                               fvalue_to_string_repr(&finfo->value,
+                                   FTREPR_DFILTER,
+                                   &(*filter)[abbrev_len + 4]);
+                       }
                        break;
        }
 
-       return buf;
+       return TRUE;
 }
index 1f8af93e2ddef11ee0b7bbff8cb45281da68a8e3..78c1096843fea4e32aef4c932de461a23ca31be5 100644 (file)
@@ -1532,19 +1532,16 @@ hfinfo_bitwidth(header_field_info *hfinfo);
 
 #include "epan.h"
 
-/** Can we do a "match selected" on this field.
+/** Check whether we can do a "match selected" on this field and, if
+    requested to, return the filter that does so.
  @param finfo field_info
  @param edt epan dissecting
+ @param filter if non-null, the display filter string is constructed and
+ *filter is set to point to it
  @return TRUE if we can do a "match selected" on the field, FALSE otherwise. */
 extern gboolean
-proto_can_match_selected(field_info *finfo, epan_dissect_t *edt);
-
-/** Construct a display filter string.
- @param finfo field_info
- @param edt epan dissecting
- @return the display filter string */
-extern char*
-proto_construct_dfilter_string(field_info *finfo, epan_dissect_t *edt);
+proto_construct_match_selected_string(field_info *finfo, epan_dissect_t *edt,
+    char **filter);
 
 /** Find field from offset in tvb.
  @param tree 
index c44f7e64cc932d58427693546cab45161eca4430..607baa7a38d9c7c4b94569ac68b202da82a7521d 100644 (file)
@@ -716,9 +716,9 @@ init_error_table_row(error_equiv_table *err, const expert_info_t *expert_data)
             err->procedures[err->num_procs].entries[j]=NULL;
        }
         err->procedures[err->num_procs].packet_num = (guint32)expert_data->packet_num;                        /* First packet num */
-       err->procedures[err->num_procs].entries[0]=(char *)g_strdup_printf("%s", val_to_str(expert_data->group, expert_group_vals,"Unknown group (%u)"), NULL);   /* Group */
-        err->procedures[err->num_procs].entries[1]=(char *)g_strdup_printf("%s", expert_data->protocol, NULL);    /* Protocol */
-        err->procedures[err->num_procs].entries[2]=(char *)g_strdup_printf("%s", expert_data->summary, NULL);     /* Summary */
+       err->procedures[err->num_procs].entries[0]=(char *)g_strdup(val_to_str(expert_data->group, expert_group_vals,"Unknown group (%u)"), NULL);   /* Group */
+        err->procedures[err->num_procs].entries[1]=(char *)g_strdup(expert_data->protocol, NULL);    /* Protocol */
+        err->procedures[err->num_procs].entries[2]=(char *)g_strdup(expert_data->summary, NULL);     /* Summary */
        err->procedures[err->num_procs].entries[3]=(char *)g_strdup_printf("%d", err->procedures[row].count);     /* Count */
         err->procedures[err->num_procs].fvalue_value = NULL;
     }
@@ -734,22 +734,24 @@ init_error_table_row(error_equiv_table *err, const expert_info_t *expert_data)
         }
         
         /* Create the item in our memory table */
-        err->procedures[row].entries[0]=(char *)g_strdup_printf("%s", val_to_str(expert_data->group, expert_group_vals,"Unknown group (%u)"));  /* Group */
-        err->procedures[row].entries[1]=(char *)g_strdup_printf("%s", expert_data->protocol);    /* Protocol */
-        err->procedures[row].entries[2]=(char *)g_strdup_printf("%s", expert_data->summary);     /* Summary */
+        err->procedures[row].entries[0]=(char *)g_strdup(val_to_str(expert_data->group, expert_group_vals,"Unknown group (%u)"));  /* Group */
+        err->procedures[row].entries[1]=(char *)g_strdup(expert_data->protocol);    /* Protocol */
+        err->procedures[row].entries[2]=(char *)g_strdup(expert_data->summary);     /* Summary */
 
         /* Create a new item in our tree view */
         store = GTK_TREE_STORE(gtk_tree_view_get_model(err->tree_view)); /* Get store */
         gtk_tree_store_append (store, &err->procedures[row].iter, NULL);  /* Acquire an iterator */
         
         gtk_tree_store_set (store, &err->procedures[row].iter,
-                    GROUP_COLUMN, (char *)g_strdup_printf("%s", val_to_str(expert_data->group, expert_group_vals,"Unknown group (%u)")),
-                    PROTOCOL_COLUMN, (char *)g_strdup_printf("%s", expert_data->protocol),
-                    SUMMARY_COLUMN, (char *)g_strdup_printf("%s", expert_data->summary), -1);
+                    GROUP_COLUMN, (char *)g_strdup(val_to_str(expert_data->group, expert_group_vals,"Unknown group (%u)")),
+                    PROTOCOL_COLUMN, (char *)g_strdup(expert_data->protocol),
+                    SUMMARY_COLUMN, (char *)g_strdup(expert_data->summary), -1);
 
         /* If an expert item was passed then build the filter string */
-        if (expert_data->pitem && strcmp(expert_data->pitem->finfo->value.ftype->name,"FT_NONE")!=0) {
-            err->procedures[row].fvalue_value = g_strdup_printf("%s", proto_construct_dfilter_string(expert_data->pitem->finfo, NULL));
+        if (expert_data->pitem) {
+            char *filter;
+            if (proto_construct_match_selected_string(expert_data->pitem->finfo, NULL, &filter))
+                err->procedures[row].fvalue_value = g_strdup(filter);
         }
         /* Store the updated count of events */
         err->num_procs = ++old_num_procs;
index fea58b0f88bab465dc59e05a23a60f283447377c..e4d37fa9d441786ea5f4fa7cb14a19413f54b28b 100644 (file)
@@ -306,10 +306,13 @@ match_selected_cb_do(gpointer data, int action, gchar *text)
 void
 match_selected_ptree_cb(GtkWidget *w, gpointer data, MATCH_SELECTED_E action)
 {
-    if (cfile.finfo_selected)
-       match_selected_cb_do((data ? data : w),
-           action,
-           proto_construct_dfilter_string(cfile.finfo_selected, cfile.edt));
+    char *filter;
+
+    if (cfile.finfo_selected) {
+        if (proto_construct_match_selected_string(cfile.finfo_selected,
+                                                  cfile.edt, &filter))
+            match_selected_cb_do((data ? data : w), action, filter);
+    }
 }
 
 
index 86e0e5a2b6689de4805d1d84d889773ee94d8ea3..aa0470714076219405d3c960e969f27d3ca47901 100644 (file)
@@ -2430,13 +2430,13 @@ set_menus_for_selected_tree_row(capture_file *cf)
        set_menu_sensitivity(tree_view_menu_factory,
          "/Go to Corresponding Packet", hfinfo->type == FT_FRAMENUM);
        set_menu_sensitivity(main_menu_factory, "/Analyze/Apply as Filter",
-         proto_can_match_selected(cf->finfo_selected, cf->edt));
+         proto_construct_match_selected_string(cf->finfo_selected, cf->edt, NULL));
        set_menu_sensitivity(tree_view_menu_factory, "/Apply as Filter",
-         proto_can_match_selected(cf->finfo_selected, cf->edt));
+         proto_construct_match_selected_string(cf->finfo_selected, cf->edt, NULL));
        set_menu_sensitivity(main_menu_factory, "/Analyze/Prepare a Filter",
-         proto_can_match_selected(cf->finfo_selected, cf->edt));
+         proto_construct_match_selected_string(cf->finfo_selected, cf->edt, NULL));
        set_menu_sensitivity(tree_view_menu_factory, "/Prepare a Filter",
-         proto_can_match_selected(cf->finfo_selected, cf->edt));
+         proto_construct_match_selected_string(cf->finfo_selected, cf->edt, NULL));
        set_menu_sensitivity(tree_view_menu_factory, "/Protocol Preferences...",
          properties);
        set_menu_sensitivity(main_menu_factory, "/View/Expand Subtrees", cf->finfo_selected->tree_type != -1);
diff --git a/print.c b/print.c
index af67bec5fa8b83bb143e240aeaeb4d049da5fc71..ed5a3ba74d6f62e1aa94b09f9b79db048887d95a 100644 (file)
--- a/print.c
+++ b/print.c
@@ -343,9 +343,8 @@ proto_tree_write_node_pdml(proto_node *node, gpointer data)
                default:
                        /* XXX - this is a hack until we can just call
                         * fvalue_to_string_repr() for *all* FT_* types. */
-                       dfilter_string = proto_construct_dfilter_string(fi,
-                                       pdata->edt);
-                       if (dfilter_string != NULL) {
+                       if (proto_construct_match_selected_string(fi,
+                           pdata->edt, &dfilter_string)) {
                                chop_len = strlen(fi->hfinfo->abbrev) + 4; /* for " == " */
 
                                /* XXX - Remove double-quotes. Again, once we
index 484df8090585d03aa6fa0adbf9fa3105745e8059..0c9f8fbfc454fdb0b0ffb2fc56519b29cb23a9ce 100644 (file)
@@ -76,8 +76,7 @@ protocolinfo_packet(void *prs, packet_info *pinfo, epan_dissect_t *edt, const vo
        }
 
        for(i=0;i<gp->len;i++){
-               str=proto_construct_dfilter_string(gp->pdata[i], NULL);
-               if(str){
+               if(proto_construct_match_selected_string(gp->pdata[i], NULL, &str)){
                        col_append_fstr(pinfo->cinfo, COL_INFO, "  %s",str);
                }
        }