ofp-util: Work on decoding OF1.1 flow_mods.
[openvswitch] / lib / table.c
index 86366d0dca90cdaf2bf3e6f1e5771901f585a01b..f24ddc62e5cde843334c9dd117e37000157b78b1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, 2011 Nicira Networks.
+ * Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,6 +23,8 @@
 #include "dynamic-string.h"
 #include "json.h"
 #include "ovsdb-data.h"
+#include "ovsdb-error.h"
+#include "timeval.h"
 #include "util.h"
 
 struct column {
@@ -54,6 +56,7 @@ cell_to_text(struct cell *cell, const struct table_style *style)
                     cell->text = ds_steal_cstr(&s);
                 } else {
                     cell->text = json_to_string(cell->json, JSSF_SORT);
+                    ovsdb_error_destroy(error);
                 }
             }
         } else {
@@ -121,6 +124,14 @@ table_set_caption(struct table *table, char *caption)
     table->caption = caption;
 }
 
+/* Turns printing a timestamp along with 'table' on or off, according to
+ * 'timestamp'.  */
+void
+table_set_timestamp(struct table *table, bool timestamp)
+{
+    table->timestamp = timestamp;
+}
+
 /* Adds a new column to 'table' just to the right of any existing column, with
  * 'heading' as a title for the column.  'heading' must be a valid printf()
  * format specifier.
@@ -209,6 +220,24 @@ table_print_table_line__(struct ds *line)
     ds_clear(line);
 }
 
+static void
+table_format_timestamp__(char *s, size_t size)
+{
+    time_t now = time_wall();
+    strftime(s, size, "%Y-%m-%d %H:%M:%S", gmtime(&now));
+}
+
+static void
+table_print_timestamp__(const struct table *table)
+{
+    if (table->timestamp) {
+        char s[32];
+
+        table_format_timestamp__(s, sizeof s);
+        puts(s);
+    }
+}
+
 static void
 table_print_table__(const struct table *table, const struct table_style *style)
 {
@@ -221,6 +250,8 @@ table_print_table__(const struct table *table, const struct table_style *style)
         putchar('\n');
     }
 
+    table_print_timestamp__(table);
+
     if (table->caption) {
         puts(table->caption);
     }
@@ -284,6 +315,8 @@ table_print_list__(const struct table *table, const struct table_style *style)
         putchar('\n');
     }
 
+    table_print_timestamp__(table);
+
     if (table->caption) {
         puts(table->caption);
     }
@@ -355,6 +388,8 @@ table_print_html__(const struct table *table, const struct table_style *style)
 {
     size_t x, y;
 
+    table_print_timestamp__(table);
+
     fputs("<table border=1>\n", stdout);
 
     if (table->caption) {
@@ -425,6 +460,8 @@ table_print_csv__(const struct table *table, const struct table_style *style)
         putchar('\n');
     }
 
+    table_print_timestamp__(table);
+
     if (table->caption) {
         puts(table->caption);
     }
@@ -463,6 +500,12 @@ table_print_json__(const struct table *table, const struct table_style *style)
     if (table->caption) {
         json_object_put_string(json, "caption", table->caption);
     }
+    if (table->timestamp) {
+        char s[32];
+
+        table_format_timestamp__(s, sizeof s);
+        json_object_put_string(json, "time", s);
+    }
 
     headings = json_array_create_empty();
     for (x = 0; x < table->n_columns; x++) {
@@ -478,8 +521,10 @@ table_print_json__(const struct table *table, const struct table_style *style)
             const struct cell *cell = table_cell__(table, y, x);
             if (cell->text) {
                 json_array_add(row, json_string_create(cell->text));
-            } else {
+            } else if (cell->json) {
                 json_array_add(row, json_clone(cell->json));
+            } else {
+                json_array_add(row, json_null_create());
             }
         }
         json_array_add(data, row);