提交 0b7593e0 编写于 作者: P Paolo Bonzini 提交者: Andreas Färber

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: NIgor Mammedov <imammedo@redhat.com>
Reviewed-by: NEric Blake <eblake@redhat.com>
Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: NAndreas Färber <afaerber@suse.de>
上级 98a65284
......@@ -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);
......
......@@ -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);
/**
......
......@@ -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;
......
......@@ -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);
......
......@@ -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);
......
......@@ -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);
......
......@@ -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;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册