aboutsummaryrefslogtreecommitdiff
path: root/qapi
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2014-02-08 11:01:50 +0100
committerAndreas Färber <afaerber@suse.de>2014-02-14 21:12:03 +0100
commit0b7593e085e66c7f5ab980a1ed8ee683c36b7347 (patch)
treef883f5fc027994008c1e5a214d5b36100c7ad1ee /qapi
parent98a6528461acf7a6f321d846e6f4e77e87305965 (diff)
qapi: Add human mode to StringOutputVisitor
This will be used by "info qtree". For numbers it prints both the decimal and hex values. For sizes it rounds to the nearest power of 2^10. For strings, it puts quotes around the string and separates NULL and empty string. Reviewed-by: Igor Mammedov <imammedo@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Andreas Färber <afaerber@suse.de>
Diffstat (limited to 'qapi')
-rw-r--r--qapi/string-output-visitor.c55
1 files changed, 52 insertions, 3 deletions
diff --git a/qapi/string-output-visitor.c b/qapi/string-output-visitor.c
index 921653d425..67a8798292 100644
--- a/qapi/string-output-visitor.c
+++ b/qapi/string-output-visitor.c
@@ -14,10 +14,12 @@
#include "qapi/string-output-visitor.h"
#include "qapi/visitor-impl.h"
#include "qapi/qmp/qerror.h"
+#include "qemu/host-utils.h"
struct StringOutputVisitor
{
Visitor visitor;
+ bool human;
char *string;
};
@@ -31,7 +33,45 @@ static void print_type_int(Visitor *v, int64_t *obj, const char *name,
Error **errp)
{
StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
- string_output_set(sov, g_strdup_printf("%lld", (long long) *obj));
+ char *out;
+
+ if (sov->human) {
+ out = g_strdup_printf("%lld (%#llx)", (long long) *obj, (long long) *obj);
+ } else {
+ out = g_strdup_printf("%lld", (long long) *obj);
+ }
+ string_output_set(sov, out);
+}
+
+static void print_type_size(Visitor *v, uint64_t *obj, const char *name,
+ Error **errp)
+{
+ StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
+ static const char suffixes[] = { 'B', 'K', 'M', 'G', 'T' };
+ uint64_t div, val;
+ char *out;
+ int i;
+
+ if (!sov->human) {
+ out = g_strdup_printf("%llu", (long long) *obj);
+ string_output_set(sov, out);
+ return;
+ }
+
+ val = *obj;
+
+ /* Compute floor(log2(val)). */
+ i = 64 - clz64(val);
+
+ /* Find the power of 1024 that we'll display as the units. */
+ i /= 10;
+ if (i >= ARRAY_SIZE(suffixes)) {
+ i = ARRAY_SIZE(suffixes) - 1;
+ }
+ div = 1ULL << (i * 10);
+
+ out = g_strdup_printf("%0.03f%c", (double)val/div, suffixes[i]);
+ string_output_set(sov, out);
}
static void print_type_bool(Visitor *v, bool *obj, const char *name,
@@ -45,7 +85,14 @@ static void print_type_str(Visitor *v, char **obj, const char *name,
Error **errp)
{
StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
- string_output_set(sov, g_strdup(*obj ? *obj : ""));
+ char *out;
+
+ if (sov->human) {
+ out = *obj ? g_strdup_printf("\"%s\"", *obj) : g_strdup("<null>");
+ } else {
+ out = g_strdup(*obj ? *obj : "");
+ }
+ string_output_set(sov, out);
}
static void print_type_number(Visitor *v, double *obj, const char *name,
@@ -73,14 +120,16 @@ void string_output_visitor_cleanup(StringOutputVisitor *sov)
g_free(sov);
}
-StringOutputVisitor *string_output_visitor_new(void)
+StringOutputVisitor *string_output_visitor_new(bool human)
{
StringOutputVisitor *v;
v = g_malloc0(sizeof(*v));
+ v->human = human;
v->visitor.type_enum = output_type_enum;
v->visitor.type_int = print_type_int;
+ v->visitor.type_size = print_type_size;
v->visitor.type_bool = print_type_bool;
v->visitor.type_str = print_type_str;
v->visitor.type_number = print_type_number;