~ubuntu-branches/ubuntu/vivid/qemu-linaro/vivid

« back to all changes in this revision

Viewing changes to qapi/qmp-input-visitor.c

  • Committer: Ricardo Salveti de Araujo
  • Date: 2012-09-20 18:39:31 UTC
  • mfrom: (12922.1.2 qemu-linaro)
  • Revision ID: ricardo.salveti@linaro.org-20120920183931-sp3cg6kpdl8dmwo9
* New upstream release.
  - support emulated systems with more than 2G of memory. (LP: #1030588)
* Drop powerpc-missing-include.patch - merged upstream.
* Update debian/control:
  - drop perl build dependency.
  - add libfdt-dev build dependency.
* Update debian/qemu-keymaps.install file.
* Update debian/rules:
  - update QEMU_CPU for ARM architecture: armv4l -> armv7l.
  - update conf_audio_drv: default to PulseAudio since PA is the default on
    Ubuntu.
  - enable KVM on ARM architecture.
  - enable flat device tree support (--enable-fdt). (LP: #1030594)

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 
23
23
typedef struct StackObject
24
24
{
25
 
    const QObject *obj;
26
 
    const  QListEntry *entry;
 
25
    QObject *obj;
 
26
    const QListEntry *entry;
 
27
    GHashTable *h;
27
28
} StackObject;
28
29
 
29
30
struct QmpInputVisitor
30
31
{
31
32
    Visitor visitor;
32
 
    QObject *obj;
33
33
    StackObject stack[QIV_STACK_SIZE];
34
34
    int nb_stack;
 
35
    bool strict;
35
36
};
36
37
 
37
38
static QmpInputVisitor *to_qiv(Visitor *v)
39
40
    return container_of(v, QmpInputVisitor, visitor);
40
41
}
41
42
 
42
 
static const QObject *qmp_input_get_object(QmpInputVisitor *qiv,
43
 
                                           const char *name)
 
43
static QObject *qmp_input_get_object(QmpInputVisitor *qiv,
 
44
                                     const char *name)
44
45
{
45
 
    const QObject *qobj;
46
 
 
47
 
    if (qiv->nb_stack == 0) {
48
 
        qobj = qiv->obj;
49
 
    } else {
50
 
        qobj = qiv->stack[qiv->nb_stack - 1].obj;
51
 
    }
 
46
    QObject *qobj = qiv->stack[qiv->nb_stack - 1].obj;
52
47
 
53
48
    if (qobj) {
54
49
        if (name && qobject_type(qobj) == QTYPE_QDICT) {
 
50
            if (qiv->stack[qiv->nb_stack - 1].h) {
 
51
                g_hash_table_remove(qiv->stack[qiv->nb_stack - 1].h, name);
 
52
            }
55
53
            return qdict_get(qobject_to_qdict(qobj), name);
56
 
        } else if (qiv->nb_stack > 0 && qobject_type(qobj) == QTYPE_QLIST) {
 
54
        } else if (qiv->stack[qiv->nb_stack - 1].entry) {
57
55
            return qlist_entry_obj(qiv->stack[qiv->nb_stack - 1].entry);
58
56
        }
59
57
    }
61
59
    return qobj;
62
60
}
63
61
 
64
 
static void qmp_input_push(QmpInputVisitor *qiv, const QObject *obj, Error **errp)
65
 
{
 
62
static void qdict_add_key(const char *key, QObject *obj, void *opaque)
 
63
{
 
64
    GHashTable *h = opaque;
 
65
    g_hash_table_insert(h, (gpointer) key, NULL);
 
66
}
 
67
 
 
68
static void qmp_input_push(QmpInputVisitor *qiv, QObject *obj, Error **errp)
 
69
{
 
70
    GHashTable *h;
 
71
 
 
72
    if (qiv->nb_stack >= QIV_STACK_SIZE) {
 
73
        error_set(errp, QERR_BUFFER_OVERRUN);
 
74
        return;
 
75
    }
 
76
 
66
77
    qiv->stack[qiv->nb_stack].obj = obj;
67
 
    if (qobject_type(obj) == QTYPE_QLIST) {
68
 
        qiv->stack[qiv->nb_stack].entry = qlist_first(qobject_to_qlist(obj));
 
78
    qiv->stack[qiv->nb_stack].entry = NULL;
 
79
    qiv->stack[qiv->nb_stack].h = NULL;
 
80
 
 
81
    if (qiv->strict && qobject_type(obj) == QTYPE_QDICT) {
 
82
        h = g_hash_table_new(g_str_hash, g_str_equal);
 
83
        qdict_iter(qobject_to_qdict(obj), qdict_add_key, h);
 
84
        qiv->stack[qiv->nb_stack].h = h;
69
85
    }
 
86
 
70
87
    qiv->nb_stack++;
 
88
}
71
89
 
72
 
    if (qiv->nb_stack >= QIV_STACK_SIZE) {
73
 
        error_set(errp, QERR_BUFFER_OVERRUN);
74
 
        return;
75
 
    }
 
90
/** Only for qmp_input_pop. */
 
91
static gboolean always_true(gpointer key, gpointer val, gpointer user_pkey)
 
92
{
 
93
    *(const char **)user_pkey = (const char *)key;
 
94
    return TRUE;
76
95
}
77
96
 
78
97
static void qmp_input_pop(QmpInputVisitor *qiv, Error **errp)
79
98
{
 
99
    assert(qiv->nb_stack > 0);
 
100
 
 
101
    if (qiv->strict) {
 
102
        GHashTable * const top_ht = qiv->stack[qiv->nb_stack - 1].h;
 
103
        if (top_ht) {
 
104
            if (g_hash_table_size(top_ht)) {
 
105
                const char *key;
 
106
                g_hash_table_find(top_ht, always_true, &key);
 
107
                error_set(errp, QERR_QMP_EXTRA_MEMBER, key);
 
108
            }
 
109
            g_hash_table_unref(top_ht);
 
110
        }
 
111
    }
 
112
 
80
113
    qiv->nb_stack--;
81
 
    if (qiv->nb_stack < 0) {
82
 
        error_set(errp, QERR_BUFFER_OVERRUN);
83
 
        return;
84
 
    }
85
114
}
86
115
 
87
116
static void qmp_input_start_struct(Visitor *v, void **obj, const char *kind,
88
117
                                   const char *name, size_t size, Error **errp)
89
118
{
90
119
    QmpInputVisitor *qiv = to_qiv(v);
91
 
    const QObject *qobj = qmp_input_get_object(qiv, name);
 
120
    QObject *qobj = qmp_input_get_object(qiv, name);
 
121
    Error *err = NULL;
92
122
 
93
123
    if (!qobj || qobject_type(qobj) != QTYPE_QDICT) {
94
124
        error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
96
126
        return;
97
127
    }
98
128
 
99
 
    qmp_input_push(qiv, qobj, errp);
100
 
    if (error_is_set(errp)) {
 
129
    qmp_input_push(qiv, qobj, &err);
 
130
    if (err) {
 
131
        error_propagate(errp, err);
101
132
        return;
102
133
    }
103
134
 
116
147
static void qmp_input_start_list(Visitor *v, const char *name, Error **errp)
117
148
{
118
149
    QmpInputVisitor *qiv = to_qiv(v);
119
 
    const QObject *qobj = qmp_input_get_object(qiv, name);
 
150
    QObject *qobj = qmp_input_get_object(qiv, name);
120
151
 
121
152
    if (!qobj || qobject_type(qobj) != QTYPE_QLIST) {
122
153
        error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
133
164
    QmpInputVisitor *qiv = to_qiv(v);
134
165
    GenericList *entry;
135
166
    StackObject *so = &qiv->stack[qiv->nb_stack - 1];
 
167
    bool first;
 
168
 
 
169
    if (so->entry == NULL) {
 
170
        so->entry = qlist_first(qobject_to_qlist(so->obj));
 
171
        first = true;
 
172
    } else {
 
173
        so->entry = qlist_next(so->entry);
 
174
        first = false;
 
175
    }
136
176
 
137
177
    if (so->entry == NULL) {
138
178
        return NULL;
139
179
    }
140
180
 
141
181
    entry = g_malloc0(sizeof(*entry));
142
 
    if (*list) {
143
 
        so->entry = qlist_next(so->entry);
144
 
        if (so->entry == NULL) {
145
 
            g_free(entry);
146
 
            return NULL;
147
 
        }
 
182
    if (first) {
 
183
        *list = entry;
 
184
    } else {
148
185
        (*list)->next = entry;
149
186
    }
150
187
 
162
199
                               Error **errp)
163
200
{
164
201
    QmpInputVisitor *qiv = to_qiv(v);
165
 
    const QObject *qobj = qmp_input_get_object(qiv, name);
 
202
    QObject *qobj = qmp_input_get_object(qiv, name);
166
203
 
167
204
    if (!qobj || qobject_type(qobj) != QTYPE_QINT) {
168
205
        error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
177
214
                                Error **errp)
178
215
{
179
216
    QmpInputVisitor *qiv = to_qiv(v);
180
 
    const QObject *qobj = qmp_input_get_object(qiv, name);
 
217
    QObject *qobj = qmp_input_get_object(qiv, name);
181
218
 
182
219
    if (!qobj || qobject_type(qobj) != QTYPE_QBOOL) {
183
220
        error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
192
229
                               Error **errp)
193
230
{
194
231
    QmpInputVisitor *qiv = to_qiv(v);
195
 
    const QObject *qobj = qmp_input_get_object(qiv, name);
 
232
    QObject *qobj = qmp_input_get_object(qiv, name);
196
233
 
197
234
    if (!qobj || qobject_type(qobj) != QTYPE_QSTRING) {
198
235
        error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
207
244
                                  Error **errp)
208
245
{
209
246
    QmpInputVisitor *qiv = to_qiv(v);
210
 
    const QObject *qobj = qmp_input_get_object(qiv, name);
 
247
    QObject *qobj = qmp_input_get_object(qiv, name);
211
248
 
212
 
    if (!qobj || qobject_type(qobj) != QTYPE_QFLOAT) {
 
249
    if (!qobj || (qobject_type(qobj) != QTYPE_QFLOAT &&
 
250
        qobject_type(qobj) != QTYPE_QINT)) {
213
251
        error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
214
 
                  "double");
 
252
                  "number");
215
253
        return;
216
254
    }
217
255
 
218
 
    *obj = qfloat_get_double(qobject_to_qfloat(qobj));
 
256
    if (qobject_type(qobj) == QTYPE_QINT) {
 
257
        *obj = qint_get_int(qobject_to_qint(qobj));
 
258
    } else {
 
259
        *obj = qfloat_get_double(qobject_to_qfloat(qobj));
 
260
    }
219
261
}
220
262
 
221
263
static void qmp_input_start_optional(Visitor *v, bool *present,
222
264
                                     const char *name, Error **errp)
223
265
{
224
266
    QmpInputVisitor *qiv = to_qiv(v);
225
 
    const QObject *qobj = qmp_input_get_object(qiv, name);
 
267
    QObject *qobj = qmp_input_get_object(qiv, name);
226
268
 
227
269
    if (!qobj) {
228
270
        *present = false;
239
281
 
240
282
void qmp_input_visitor_cleanup(QmpInputVisitor *v)
241
283
{
242
 
    qobject_decref(v->obj);
 
284
    qobject_decref(v->stack[0].obj);
243
285
    g_free(v);
244
286
}
245
287
 
261
303
    v->visitor.type_number = qmp_input_type_number;
262
304
    v->visitor.start_optional = qmp_input_start_optional;
263
305
 
264
 
    v->obj = obj;
265
 
    qobject_incref(v->obj);
 
306
    qmp_input_push(v, obj, NULL);
 
307
    qobject_incref(obj);
 
308
 
 
309
    return v;
 
310
}
 
311
 
 
312
QmpInputVisitor *qmp_input_visitor_new_strict(QObject *obj)
 
313
{
 
314
    QmpInputVisitor *v;
 
315
 
 
316
    v = qmp_input_visitor_new(obj);
 
317
    v->strict = true;
266
318
 
267
319
    return v;
268
320
}