remove glib dependency by provide compatible replacements
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
util-obj-y = qapi-visit-core.o qapi-dealloc-visitor.o qmp-input-visitor.o
|
||||
util-obj-y += qmp-output-visitor.o
|
||||
util-obj-y += string-input-visitor.o string-output-visitor.o
|
||||
util-obj-y += string-input-visitor.o
|
||||
|
||||
@@ -55,7 +55,7 @@ static void *qapi_dealloc_pop(QapiDeallocVisitor *qov)
|
||||
QObject *value;
|
||||
QTAILQ_REMOVE(&qov->stack, e, node);
|
||||
value = e->value;
|
||||
g_free(e);
|
||||
free(e);
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ static void qapi_dealloc_end_struct(Visitor *v, Error **errp)
|
||||
QapiDeallocVisitor *qov = to_qov(v);
|
||||
void **obj = qapi_dealloc_pop(qov);
|
||||
if (obj) {
|
||||
g_free(*obj);
|
||||
free(*obj);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ static void qapi_dealloc_end_implicit_struct(Visitor *v, Error **errp)
|
||||
QapiDeallocVisitor *qov = to_qov(v);
|
||||
void **obj = qapi_dealloc_pop(qov);
|
||||
if (obj) {
|
||||
g_free(*obj);
|
||||
free(*obj);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ static GenericList *qapi_dealloc_next_list(Visitor *v, GenericList **listp,
|
||||
|
||||
if (list) {
|
||||
list = list->next;
|
||||
g_free(*listp);
|
||||
free(*listp);
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ static void qapi_dealloc_type_str(Visitor *v, char **obj, const char *name,
|
||||
Error **errp)
|
||||
{
|
||||
if (obj) {
|
||||
g_free(*obj);
|
||||
free(*obj);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ Visitor *qapi_dealloc_get_visitor(QapiDeallocVisitor *v)
|
||||
|
||||
void qapi_dealloc_visitor_cleanup(QapiDeallocVisitor *v)
|
||||
{
|
||||
g_free(v);
|
||||
free(v);
|
||||
}
|
||||
|
||||
QapiDeallocVisitor *qapi_dealloc_visitor_new(void)
|
||||
|
||||
@@ -304,10 +304,10 @@ void input_type_enum(Visitor *v, int *obj, const char *strings[],
|
||||
|
||||
if (strings[value] == NULL) {
|
||||
error_set(errp, QERR_INVALID_PARAMETER, enum_str);
|
||||
g_free(enum_str);
|
||||
free(enum_str);
|
||||
return;
|
||||
}
|
||||
|
||||
g_free(enum_str);
|
||||
free(enum_str);
|
||||
*obj = value;
|
||||
}
|
||||
|
||||
@@ -308,7 +308,7 @@ Visitor *qmp_input_get_visitor(QmpInputVisitor *v)
|
||||
void qmp_input_visitor_cleanup(QmpInputVisitor *v)
|
||||
{
|
||||
qobject_decref(v->stack[0].obj);
|
||||
g_free(v);
|
||||
free(v);
|
||||
}
|
||||
|
||||
QmpInputVisitor *qmp_input_visitor_new(QObject *obj)
|
||||
|
||||
@@ -59,7 +59,7 @@ static QObject *qmp_output_pop(QmpOutputVisitor *qov)
|
||||
QObject *value;
|
||||
QTAILQ_REMOVE(&qov->stack, e, node);
|
||||
value = e->value;
|
||||
g_free(e);
|
||||
free(e);
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -211,11 +211,11 @@ void qmp_output_visitor_cleanup(QmpOutputVisitor *v)
|
||||
|
||||
QTAILQ_FOREACH_SAFE(e, &v->stack, node, tmp) {
|
||||
QTAILQ_REMOVE(&v->stack, e, node);
|
||||
g_free(e);
|
||||
free(e);
|
||||
}
|
||||
|
||||
qobject_decref(root);
|
||||
g_free(v);
|
||||
free(v);
|
||||
}
|
||||
|
||||
QmpOutputVisitor *qmp_output_visitor_new(void)
|
||||
|
||||
@@ -34,7 +34,7 @@ struct StringInputVisitor
|
||||
|
||||
static void free_range(void *range, void *dummy)
|
||||
{
|
||||
g_free(range);
|
||||
free(range);
|
||||
}
|
||||
|
||||
static void parse_str(StringInputVisitor *siv, Error **errp)
|
||||
@@ -321,7 +321,7 @@ void string_input_visitor_cleanup(StringInputVisitor *v)
|
||||
{
|
||||
g_list_foreach(v->ranges, free_range, NULL);
|
||||
g_list_free(v->ranges);
|
||||
g_free(v);
|
||||
free(v);
|
||||
}
|
||||
|
||||
StringInputVisitor *string_input_visitor_new(const char *str)
|
||||
|
||||
@@ -1,354 +0,0 @@
|
||||
/*
|
||||
* String printing Visitor
|
||||
*
|
||||
* Copyright Red Hat, Inc. 2012
|
||||
*
|
||||
* Author: Paolo Bonzini <pbonzini@redhat.com>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
||||
* See the COPYING.LIB file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "qapi/string-output-visitor.h"
|
||||
#include "qapi/visitor-impl.h"
|
||||
#include "qapi/qmp/qerror.h"
|
||||
#include "qemu/host-utils.h"
|
||||
#include <math.h>
|
||||
#include "qemu/range.h"
|
||||
|
||||
enum ListMode {
|
||||
LM_NONE, /* not traversing a list of repeated options */
|
||||
LM_STARTED, /* start_list() succeeded */
|
||||
|
||||
LM_IN_PROGRESS, /* next_list() has been called.
|
||||
*
|
||||
* Generating the next list link will consume the most
|
||||
* recently parsed QemuOpt instance of the repeated
|
||||
* option.
|
||||
*
|
||||
* Parsing a value into the list link will examine the
|
||||
* next QemuOpt instance of the repeated option, and
|
||||
* possibly enter LM_SIGNED_INTERVAL or
|
||||
* LM_UNSIGNED_INTERVAL.
|
||||
*/
|
||||
|
||||
LM_SIGNED_INTERVAL, /* next_list() has been called.
|
||||
*
|
||||
* Generating the next list link will consume the most
|
||||
* recently stored element from the signed interval,
|
||||
* parsed from the most recent QemuOpt instance of the
|
||||
* repeated option. This may consume QemuOpt itself
|
||||
* and return to LM_IN_PROGRESS.
|
||||
*
|
||||
* Parsing a value into the list link will store the
|
||||
* next element of the signed interval.
|
||||
*/
|
||||
|
||||
LM_UNSIGNED_INTERVAL,/* Same as above, only for an unsigned interval. */
|
||||
|
||||
LM_END
|
||||
};
|
||||
|
||||
typedef enum ListMode ListMode;
|
||||
|
||||
struct StringOutputVisitor
|
||||
{
|
||||
Visitor visitor;
|
||||
bool human;
|
||||
GString *string;
|
||||
bool head;
|
||||
ListMode list_mode;
|
||||
union {
|
||||
int64_t s;
|
||||
uint64_t u;
|
||||
} range_start, range_end;
|
||||
GList *ranges;
|
||||
};
|
||||
|
||||
static void string_output_set(StringOutputVisitor *sov, char *string)
|
||||
{
|
||||
if (sov->string) {
|
||||
g_string_free(sov->string, true);
|
||||
}
|
||||
sov->string = g_string_new(string);
|
||||
g_free(string);
|
||||
}
|
||||
|
||||
static void string_output_append(StringOutputVisitor *sov, int64_t a)
|
||||
{
|
||||
Range *r = g_malloc0(sizeof(*r));
|
||||
r->begin = a;
|
||||
r->end = a + 1;
|
||||
sov->ranges = g_list_insert_sorted_merged(sov->ranges, r, range_compare);
|
||||
}
|
||||
|
||||
static void string_output_append_range(StringOutputVisitor *sov,
|
||||
int64_t s, int64_t e)
|
||||
{
|
||||
Range *r = g_malloc0(sizeof(*r));
|
||||
r->begin = s;
|
||||
r->end = e + 1;
|
||||
sov->ranges = g_list_insert_sorted_merged(sov->ranges, r, range_compare);
|
||||
}
|
||||
|
||||
static void format_string(StringOutputVisitor *sov, Range *r, bool next,
|
||||
bool human)
|
||||
{
|
||||
if (r->end - r->begin > 1) {
|
||||
if (human) {
|
||||
g_string_append_printf(sov->string, "0x%" PRIx64 "-0x%" PRIx64,
|
||||
r->begin, r->end - 1);
|
||||
|
||||
} else {
|
||||
g_string_append_printf(sov->string, "%" PRId64 "-%" PRId64,
|
||||
r->begin, r->end - 1);
|
||||
}
|
||||
} else {
|
||||
if (human) {
|
||||
g_string_append_printf(sov->string, "0x%" PRIx64, r->begin);
|
||||
} else {
|
||||
g_string_append_printf(sov->string, "%" PRId64, r->begin);
|
||||
}
|
||||
}
|
||||
if (next) {
|
||||
g_string_append(sov->string, ",");
|
||||
}
|
||||
}
|
||||
|
||||
static void print_type_int(Visitor *v, int64_t *obj, const char *name,
|
||||
Error **errp)
|
||||
{
|
||||
StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
|
||||
GList *l;
|
||||
|
||||
switch (sov->list_mode) {
|
||||
case LM_NONE:
|
||||
string_output_append(sov, *obj);
|
||||
break;
|
||||
|
||||
case LM_STARTED:
|
||||
sov->range_start.s = *obj;
|
||||
sov->range_end.s = *obj;
|
||||
sov->list_mode = LM_IN_PROGRESS;
|
||||
return;
|
||||
|
||||
case LM_IN_PROGRESS:
|
||||
if (sov->range_end.s + 1 == *obj) {
|
||||
sov->range_end.s++;
|
||||
} else {
|
||||
if (sov->range_start.s == sov->range_end.s) {
|
||||
string_output_append(sov, sov->range_end.s);
|
||||
} else {
|
||||
assert(sov->range_start.s < sov->range_end.s);
|
||||
string_output_append_range(sov, sov->range_start.s,
|
||||
sov->range_end.s);
|
||||
}
|
||||
|
||||
sov->range_start.s = *obj;
|
||||
sov->range_end.s = *obj;
|
||||
}
|
||||
return;
|
||||
|
||||
case LM_END:
|
||||
if (sov->range_end.s + 1 == *obj) {
|
||||
sov->range_end.s++;
|
||||
assert(sov->range_start.s < sov->range_end.s);
|
||||
string_output_append_range(sov, sov->range_start.s,
|
||||
sov->range_end.s);
|
||||
} else {
|
||||
if (sov->range_start.s == sov->range_end.s) {
|
||||
string_output_append(sov, sov->range_end.s);
|
||||
} else {
|
||||
assert(sov->range_start.s < sov->range_end.s);
|
||||
|
||||
string_output_append_range(sov, sov->range_start.s,
|
||||
sov->range_end.s);
|
||||
}
|
||||
string_output_append(sov, *obj);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
l = sov->ranges;
|
||||
while (l) {
|
||||
Range *r = l->data;
|
||||
format_string(sov, r, l->next != NULL, false);
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
if (sov->human) {
|
||||
l = sov->ranges;
|
||||
g_string_append(sov->string, " (");
|
||||
while (l) {
|
||||
Range *r = l->data;
|
||||
format_string(sov, r, l->next != NULL, true);
|
||||
l = l->next;
|
||||
}
|
||||
g_string_append(sov->string, ")");
|
||||
}
|
||||
}
|
||||
|
||||
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', 'P', 'E' };
|
||||
uint64_t div, val;
|
||||
char *out;
|
||||
int i;
|
||||
|
||||
if (!sov->human) {
|
||||
out = g_strdup_printf("%"PRIu64, *obj);
|
||||
string_output_set(sov, out);
|
||||
return;
|
||||
}
|
||||
|
||||
val = *obj;
|
||||
|
||||
/* The exponent (returned in i) minus one gives us
|
||||
* floor(log2(val * 1024 / 1000). The correction makes us
|
||||
* switch to the higher power when the integer part is >= 1000.
|
||||
*/
|
||||
frexp(val / (1000.0 / 1024.0), &i);
|
||||
i = (i - 1) / 10;
|
||||
assert(i < ARRAY_SIZE(suffixes));
|
||||
div = 1ULL << (i * 10);
|
||||
|
||||
out = g_strdup_printf("%"PRIu64" (%0.3g %c%s)", val,
|
||||
(double)val/div, suffixes[i], i ? "iB" : "");
|
||||
string_output_set(sov, out);
|
||||
}
|
||||
|
||||
static void print_type_bool(Visitor *v, bool *obj, const char *name,
|
||||
Error **errp)
|
||||
{
|
||||
StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
|
||||
string_output_set(sov, g_strdup(*obj ? "true" : "false"));
|
||||
}
|
||||
|
||||
static void print_type_str(Visitor *v, char **obj, const char *name,
|
||||
Error **errp)
|
||||
{
|
||||
StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
|
||||
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,
|
||||
Error **errp)
|
||||
{
|
||||
StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
|
||||
string_output_set(sov, g_strdup_printf("%f", *obj));
|
||||
}
|
||||
|
||||
static void
|
||||
start_list(Visitor *v, const char *name, Error **errp)
|
||||
{
|
||||
StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
|
||||
|
||||
/* we can't traverse a list in a list */
|
||||
assert(sov->list_mode == LM_NONE);
|
||||
sov->list_mode = LM_STARTED;
|
||||
sov->head = true;
|
||||
}
|
||||
|
||||
static GenericList *
|
||||
next_list(Visitor *v, GenericList **list, Error **errp)
|
||||
{
|
||||
StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
|
||||
GenericList *ret = NULL;
|
||||
if (*list) {
|
||||
if (sov->head) {
|
||||
ret = *list;
|
||||
} else {
|
||||
ret = (*list)->next;
|
||||
}
|
||||
|
||||
if (sov->head) {
|
||||
if (ret && ret->next == NULL) {
|
||||
sov->list_mode = LM_NONE;
|
||||
}
|
||||
sov->head = false;
|
||||
} else {
|
||||
if (ret && ret->next == NULL) {
|
||||
sov->list_mode = LM_END;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
end_list(Visitor *v, Error **errp)
|
||||
{
|
||||
StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
|
||||
|
||||
assert(sov->list_mode == LM_STARTED ||
|
||||
sov->list_mode == LM_END ||
|
||||
sov->list_mode == LM_NONE ||
|
||||
sov->list_mode == LM_IN_PROGRESS);
|
||||
sov->list_mode = LM_NONE;
|
||||
sov->head = true;
|
||||
|
||||
}
|
||||
|
||||
char *string_output_get_string(StringOutputVisitor *sov)
|
||||
{
|
||||
char *string = g_string_free(sov->string, false);
|
||||
sov->string = NULL;
|
||||
return string;
|
||||
}
|
||||
|
||||
Visitor *string_output_get_visitor(StringOutputVisitor *sov)
|
||||
{
|
||||
return &sov->visitor;
|
||||
}
|
||||
|
||||
static void free_range(void *range, void *dummy)
|
||||
{
|
||||
g_free(range);
|
||||
}
|
||||
|
||||
void string_output_visitor_cleanup(StringOutputVisitor *sov)
|
||||
{
|
||||
if (sov->string) {
|
||||
g_string_free(sov->string, true);
|
||||
}
|
||||
|
||||
g_list_foreach(sov->ranges, free_range, NULL);
|
||||
g_list_free(sov->ranges);
|
||||
g_free(sov);
|
||||
}
|
||||
|
||||
StringOutputVisitor *string_output_visitor_new(bool human)
|
||||
{
|
||||
StringOutputVisitor *v;
|
||||
|
||||
v = g_malloc0(sizeof(*v));
|
||||
|
||||
v->string = g_string_new(NULL);
|
||||
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;
|
||||
v->visitor.start_list = start_list;
|
||||
v->visitor.next_list = next_list;
|
||||
v->visitor.end_list = end_list;
|
||||
|
||||
return v;
|
||||
}
|
||||
Reference in New Issue
Block a user