From: Paolo Bonzini Date: Sat, 8 Feb 2014 10:01:50 +0000 (+0100) Subject: qapi: Add human mode to StringOutputVisitor X-Git-Tag: v2.0.0-rc0~81^2~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0b7593e085e66c7f5ab980a1ed8ee683c36b7347;p=thirdparty%2Fqemu.git 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 Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini Signed-off-by: Andreas Färber --- diff --git a/include/qapi/string-output-visitor.h b/include/qapi/string-output-visitor.h index ec81e42b60a..d99717f6508 100644 --- a/include/qapi/string-output-visitor.h +++ b/include/qapi/string-output-visitor.h @@ -17,7 +17,7 @@ typedef struct StringOutputVisitor StringOutputVisitor; -StringOutputVisitor *string_output_visitor_new(void); +StringOutputVisitor *string_output_visitor_new(bool human); void string_output_visitor_cleanup(StringOutputVisitor *v); char *string_output_get_string(StringOutputVisitor *v); diff --git a/include/qom/object.h b/include/qom/object.h index e0ff212cb69..9c7c361d301 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -946,12 +946,13 @@ void object_property_parse(Object *obj, const char *string, * object_property_print: * @obj: the object * @name: the name of the property + * @human: if true, print for human consumption * @errp: returns an error if this function fails * * Returns a string representation of the value of the property. The * caller shall free the string. */ -char *object_property_print(Object *obj, const char *name, +char *object_property_print(Object *obj, const char *name, bool human, Error **errp); /** diff --git a/qapi/string-output-visitor.c b/qapi/string-output-visitor.c index 921653d4256..67a87982926 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(""); + } 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; diff --git a/qdev-monitor.c b/qdev-monitor.c index 4d1634cd5f0..f385fb32a32 100644 --- a/qdev-monitor.c +++ b/qdev-monitor.c @@ -577,7 +577,7 @@ static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props, if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) { value = object_property_get_str(OBJECT(dev), legacy_name, &err); } else { - value = object_property_print(OBJECT(dev), props->name, &err); + value = object_property_print(OBJECT(dev), props->name, false, &err); } g_free(legacy_name); diff --git a/qom/object.c b/qom/object.c index 62e7e415d9b..660859c0e7f 100644 --- a/qom/object.c +++ b/qom/object.c @@ -948,13 +948,13 @@ void object_property_parse(Object *obj, const char *string, string_input_visitor_cleanup(mi); } -char *object_property_print(Object *obj, const char *name, +char *object_property_print(Object *obj, const char *name, bool human, Error **errp) { StringOutputVisitor *mo; char *string; - mo = string_output_visitor_new(); + mo = string_output_visitor_new(human); object_property_get(obj, string_output_get_visitor(mo), name, errp); string = string_output_get_string(mo); string_output_visitor_cleanup(mo); diff --git a/tests/test-string-output-visitor.c b/tests/test-string-output-visitor.c index 79d815f8885..56cc21d0784 100644 --- a/tests/test-string-output-visitor.c +++ b/tests/test-string-output-visitor.c @@ -26,7 +26,7 @@ typedef struct TestOutputVisitorData { static void visitor_output_setup(TestOutputVisitorData *data, const void *unused) { - data->sov = string_output_visitor_new(); + data->sov = string_output_visitor_new(false); g_assert(data->sov != NULL); data->ov = string_output_get_visitor(data->sov); diff --git a/tests/test-visitor-serialization.c b/tests/test-visitor-serialization.c index 9aaa5872e5b..6bff950eb6f 100644 --- a/tests/test-visitor-serialization.c +++ b/tests/test-visitor-serialization.c @@ -1083,7 +1083,7 @@ static void string_serialize(void *native_in, void **datap, { StringSerializeData *d = g_malloc0(sizeof(*d)); - d->sov = string_output_visitor_new(); + d->sov = string_output_visitor_new(false); visit(string_output_get_visitor(d->sov), &native_in, errp); *datap = d; }