|
|
1.1 root 1: /*
2: * Dealloc Visitor
3: *
4: * Copyright IBM, Corp. 2011
5: *
6: * Authors:
7: * Michael Roth <[email protected]>
8: *
9: * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
10: * See the COPYING.LIB file in the top-level directory.
11: *
12: */
13:
14: #include "qapi-dealloc-visitor.h"
15: #include "qemu-queue.h"
16: #include "qemu-common.h"
17: #include "qemu-objects.h"
18:
19: typedef struct StackEntry
20: {
21: void *value;
1.1.1.2 ! root 22: bool is_list_head;
1.1 root 23: QTAILQ_ENTRY(StackEntry) node;
24: } StackEntry;
25:
26: struct QapiDeallocVisitor
27: {
28: Visitor visitor;
29: QTAILQ_HEAD(, StackEntry) stack;
1.1.1.2 ! root 30: bool is_list_head;
1.1 root 31: };
32:
33: static QapiDeallocVisitor *to_qov(Visitor *v)
34: {
35: return container_of(v, QapiDeallocVisitor, visitor);
36: }
37:
38: static void qapi_dealloc_push(QapiDeallocVisitor *qov, void *value)
39: {
1.1.1.2 ! root 40: StackEntry *e = g_malloc0(sizeof(*e));
1.1 root 41:
42: e->value = value;
1.1.1.2 ! root 43:
! 44: /* see if we're just pushing a list head tracker */
! 45: if (value == NULL) {
! 46: e->is_list_head = true;
! 47: }
1.1 root 48: QTAILQ_INSERT_HEAD(&qov->stack, e, node);
49: }
50:
51: static void *qapi_dealloc_pop(QapiDeallocVisitor *qov)
52: {
53: StackEntry *e = QTAILQ_FIRST(&qov->stack);
54: QObject *value;
55: QTAILQ_REMOVE(&qov->stack, e, node);
56: value = e->value;
1.1.1.2 ! root 57: g_free(e);
1.1 root 58: return value;
59: }
60:
61: static void qapi_dealloc_start_struct(Visitor *v, void **obj, const char *kind,
62: const char *name, size_t unused,
63: Error **errp)
64: {
65: QapiDeallocVisitor *qov = to_qov(v);
66: qapi_dealloc_push(qov, obj);
67: }
68:
69: static void qapi_dealloc_end_struct(Visitor *v, Error **errp)
70: {
71: QapiDeallocVisitor *qov = to_qov(v);
72: void **obj = qapi_dealloc_pop(qov);
73: if (obj) {
1.1.1.2 ! root 74: g_free(*obj);
1.1 root 75: }
76: }
77:
78: static void qapi_dealloc_start_list(Visitor *v, const char *name, Error **errp)
79: {
1.1.1.2 ! root 80: QapiDeallocVisitor *qov = to_qov(v);
! 81: qapi_dealloc_push(qov, NULL);
1.1 root 82: }
83:
1.1.1.2 ! root 84: static GenericList *qapi_dealloc_next_list(Visitor *v, GenericList **listp,
1.1 root 85: Error **errp)
86: {
1.1.1.2 ! root 87: GenericList *list = *listp;
! 88: QapiDeallocVisitor *qov = to_qov(v);
! 89: StackEntry *e = QTAILQ_FIRST(&qov->stack);
! 90:
! 91: if (e && e->is_list_head) {
! 92: e->is_list_head = false;
! 93: return list;
! 94: }
! 95:
! 96: if (list) {
! 97: list = list->next;
! 98: g_free(*listp);
! 99: return list;
! 100: }
! 101:
! 102: return NULL;
1.1 root 103: }
104:
105: static void qapi_dealloc_end_list(Visitor *v, Error **errp)
106: {
1.1.1.2 ! root 107: QapiDeallocVisitor *qov = to_qov(v);
! 108: void *obj = qapi_dealloc_pop(qov);
! 109: assert(obj == NULL); /* should've been list head tracker with no payload */
1.1 root 110: }
111:
112: static void qapi_dealloc_type_str(Visitor *v, char **obj, const char *name,
113: Error **errp)
114: {
115: if (obj) {
1.1.1.2 ! root 116: g_free(*obj);
1.1 root 117: }
118: }
119:
120: static void qapi_dealloc_type_int(Visitor *v, int64_t *obj, const char *name,
121: Error **errp)
122: {
123: }
124:
125: static void qapi_dealloc_type_bool(Visitor *v, bool *obj, const char *name,
126: Error **errp)
127: {
128: }
129:
130: static void qapi_dealloc_type_number(Visitor *v, double *obj, const char *name,
131: Error **errp)
132: {
133: }
134:
135: static void qapi_dealloc_type_enum(Visitor *v, int *obj, const char *strings[],
136: const char *kind, const char *name,
137: Error **errp)
138: {
139: }
140:
141: Visitor *qapi_dealloc_get_visitor(QapiDeallocVisitor *v)
142: {
143: return &v->visitor;
144: }
145:
146: void qapi_dealloc_visitor_cleanup(QapiDeallocVisitor *v)
147: {
1.1.1.2 ! root 148: g_free(v);
1.1 root 149: }
150:
151: QapiDeallocVisitor *qapi_dealloc_visitor_new(void)
152: {
153: QapiDeallocVisitor *v;
154:
1.1.1.2 ! root 155: v = g_malloc0(sizeof(*v));
1.1 root 156:
157: v->visitor.start_struct = qapi_dealloc_start_struct;
158: v->visitor.end_struct = qapi_dealloc_end_struct;
159: v->visitor.start_list = qapi_dealloc_start_list;
160: v->visitor.next_list = qapi_dealloc_next_list;
161: v->visitor.end_list = qapi_dealloc_end_list;
162: v->visitor.type_enum = qapi_dealloc_type_enum;
163: v->visitor.type_int = qapi_dealloc_type_int;
164: v->visitor.type_bool = qapi_dealloc_type_bool;
165: v->visitor.type_str = qapi_dealloc_type_str;
166: v->visitor.type_number = qapi_dealloc_type_number;
167:
168: QTAILQ_INIT(&v->stack);
169:
170: return v;
171: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.