Add an option to print the first, the last or all occurrences of each field
authorsake <sake@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 14 Jul 2010 21:53:57 +0000 (21:53 +0000)
committersake <sake@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 14 Jul 2010 21:53:57 +0000 (21:53 +0000)
(when using tshark -T fields)

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

doc/tshark.pod
print.c
tshark.c

index 6110d19929b379eb428916695a5681236f4da2b5..9ad9eb93c385a6e0cc7b50cb9b21df1a9607aa10 100644 (file)
@@ -284,6 +284,11 @@ use for fields.  If B</t> tab will be used (this is the default), if
 B</s>, a single space will be used.  Otherwise any character that can be
 accepted by the command line as part of the option may be used.
 
+B<occurrence=f|l|a> Select which occurrence to use for fields that have
+multiple occurences.  If B<f> the first occurrence will be used, if B<l>
+the last occurrence will be used and if B<a> all occurrences will be used
+(this is the default).
+
 B<aggregator=,|/s|>E<lt>characterE<gt> Set the aggregator character to
 use for fields that have multiple occurences.  If B<,> a comma will be used
 (this is the default), if B</s>, a single space will be used.  Otherwise 
diff --git a/print.c b/print.c
index 19e2f6bcaacb4ca1526649d892d2d9146d8244a4..c734c979412fefbf666174a403b40a97fa37c8c1 100644 (file)
--- a/print.c
+++ b/print.c
@@ -75,6 +75,7 @@ typedef struct {
 struct _output_fields {
     gboolean print_header;
     gchar separator;
+    gchar occurrence;
     gchar aggregator;
     GPtrArray* fields;
     GHashTable* field_indicies;
@@ -1256,6 +1257,7 @@ output_fields_t* output_fields_new()
     output_fields_t* fields = g_new(output_fields_t, 1);
     fields->print_header = FALSE;
     fields->separator = '\t';
+    fields->occurrence = 'a';
     fields->aggregator = ',';
     fields->fields = NULL; /*Do lazy initialisation */
     fields->field_indicies = NULL;
@@ -1364,6 +1366,19 @@ gboolean output_fields_set_option(output_fields_t* info, gchar* option)
         return TRUE;
     }
 
+    if(0 == strcmp(option_name, "occurrence")) {
+        switch(NULL == option_value ? '\0' : *option_value) {
+        case 'f':
+        case 'l':
+        case 'a':
+            info->occurrence = *option_value;
+            break;
+        default:
+            return FALSE;
+        }
+        return TRUE;
+    }
+
     if(0 == strcmp(option_name,"aggregator")) {
         switch(NULL == option_value ? '\0' : *option_value) {
         case '\0':
@@ -1409,8 +1424,9 @@ gboolean output_fields_set_option(output_fields_t* info, gchar* option)
 void output_fields_list_options(FILE *fh)
 {
     fprintf(fh, "TShark: The available options for field output \"E\" are:\n");
-    fputs("header=y|n   Print field abbreviations as first line of output (def: N: no)\n", fh);
+    fputs("header=y|n    Print field abbreviations as first line of output (def: N: no)\n", fh);
     fputs("separator=/t|/s|<character>   Set the separator to use;\n     \"/t\" = tab, \"/s\" = space (def: /t: tab)\n", fh);
+    fputs("occurrence=f|l|a  Select the occurrence of a field to use;\n     \"f\" = first, \"l\" = last, \"a\" = all (def: a: all)\n", fh);
     fputs("aggregator=,|/s|<character>   Set the aggregator to use;\n     \",\" = comma, \"/s\" = space (def: ,: comma)\n", fh);
     fputs("quote=d|s|n   Print either d: double-quotes, s: single quotes or \n     n: no quotes around field values (def: n: none)\n", fh);
 }
@@ -1458,9 +1474,13 @@ static void proto_tree_get_node_field_values(proto_node *node, gpointer data)
             guint actual_index;
             actual_index = GPOINTER_TO_UINT(field_index);
             /* Unwrap change made to disambiguiate zero / null */
-            if (call_data->fields->field_values[actual_index - 1] == NULL ) {
+            if ( call_data->fields->field_values[actual_index - 1] == NULL ) {
                 call_data->fields->field_values[actual_index - 1] = ep_strbuf_new(value);
-            } else {
+            } else if ( call_data->fields->occurrence == 'l' ) {
+                /* print only the value of the last occurrence of the field */
+                ep_strbuf_printf(call_data->fields->field_values[actual_index - 1],"%s",value);
+            } else if ( call_data->fields->occurrence == 'a' ) {
+                /* print the value of all accurrences of the field */
                 ep_strbuf_append_printf(call_data->fields->field_values[actual_index - 1],
                     "%c%s",call_data->fields->aggregator,value);
             }
index 9de1469e814b85be36f02a5ef71f63d74bbb8113..68a4b3f13547faebf08f32e9dd27bbd3e7b493b2 100644 (file)
--- a/tshark.c
+++ b/tshark.c
@@ -280,6 +280,7 @@ print_usage(gboolean print_ver)
   fprintf(output, "  -E<fieldsoption>=<value> set options for output when -Tfields selected:\n");
   fprintf(output, "     header=y|n            switch headers on and off\n");
   fprintf(output, "     separator=/t|/s|<char> select tab, space, printable character as separator\n");
+  fprintf(output, "     occurrence=f|l|a      print first, last or all occurrences of each field\n");
   fprintf(output, "     aggregator=,|/s|<char> select comma, space, printable character as aggregator\n");
   fprintf(output, "     quote=d|s|n           select double, single, no quotes for values\n");
   fprintf(output, "  -t ad|a|r|d|dd|e         output format of time stamps (def: r: rel. to first)\n");