10f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes#
20f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes# QAPI visitor generator
30f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes#
40f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes# Copyright IBM, Corp. 2011
50f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes#
60f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes# Authors:
70f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes#  Anthony Liguori <aliguori@us.ibm.com>
80f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes#  Michael Roth    <mdroth@linux.vnet.ibm.com>
90f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes#
100f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes# This work is licensed under the terms of the GNU GPLv2.
110f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes# See the COPYING.LIB file in the top-level directory.
120f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes
130f3c55331439970e01af67f80ac117c473bc04cfElliott Hughesfrom ordereddict import OrderedDict
140f3c55331439970e01af67f80ac117c473bc04cfElliott Hughesfrom qapi import *
150f3c55331439970e01af67f80ac117c473bc04cfElliott Hughesimport sys
160f3c55331439970e01af67f80ac117c473bc04cfElliott Hughesimport os
177655f29fabc0a12765de828914a18314382e5a35Ian Rogersimport getopt
189651f425f7413772a7b5352da2b04eb7de7d416fIan Rogersimport errno
197410f29b4dae223befac036ea567d7f33351dad1Mathieu Chartier
207410f29b4dae223befac036ea567d7f33351dad1Mathieu Chartierdef generate_visit_struct_fields(name, field_prefix, fn_prefix, members, base = None):
21ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers    substructs = []
22ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers    ret = ''
23ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers    if not fn_prefix:
24ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers        full_name = name
25ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers    else:
264f0d07c783afef89703dce32c94440fc8621a29bIan Rogers        full_name = "%s_%s" % (name, fn_prefix)
274f0d07c783afef89703dce32c94440fc8621a29bIan Rogers
284f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    for argname, argentry, optional, structured in parse_args(members):
294f0d07c783afef89703dce32c94440fc8621a29bIan Rogers        if structured:
3057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers            if not fn_prefix:
314f0d07c783afef89703dce32c94440fc8621a29bIan Rogers                nested_fn_prefix = argname
329329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers            else:
339329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers                nested_fn_prefix = "%s_%s" % (fn_prefix, argname)
349329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers
359329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers            nested_field_prefix = "%s%s." % (field_prefix, argname)
369329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers            ret += generate_visit_struct_fields(name, nested_field_prefix,
379329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers                                                nested_fn_prefix, argentry)
389329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers
399329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    ret += mcgen('''
409329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers
419329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogersstatic void visit_type_%(full_name)s_fields(Visitor *m, %(name)s ** obj, Error **errp)
429329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers{
4315fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers    Error *err = NULL;
449329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers''',
459329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers        name=name, full_name=full_name)
464f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    push_indent()
479329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers
489329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    if base:
494f0d07c783afef89703dce32c94440fc8621a29bIan Rogers        ret += mcgen('''
504f0d07c783afef89703dce32c94440fc8621a29bIan Rogersvisit_start_implicit_struct(m, obj ? (void**) &(*obj)->%(c_name)s : NULL, sizeof(%(type)s), &err);
514f0d07c783afef89703dce32c94440fc8621a29bIan Rogersif (!err) {
524f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    visit_type_%(type)s_fields(m, obj ? &(*obj)->%(c_prefix)s%(c_name)s : NULL, &err);
531984152ac92aad244ae15184d12f9ceade686b7bMathieu Chartier    error_propagate(errp, err);
544f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    err = NULL;
554f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    visit_end_implicit_struct(m, &err);
564f0d07c783afef89703dce32c94440fc8621a29bIan Rogers}
579329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers''',
589329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers                     c_prefix=c_var(field_prefix),
599329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers                     type=type_name(base), c_name=c_var('base'))
609329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers
619329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    for argname, argentry, optional, structured in parse_args(members):
629329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers        if optional:
639329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers            ret += mcgen('''
649329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogersvisit_start_optional(m, obj ? &(*obj)->%(c_prefix)shas_%(c_name)s : NULL, "%(name)s", &err);
659329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogersif (obj && (*obj)->%(prefix)shas_%(c_name)s) {
664f0d07c783afef89703dce32c94440fc8621a29bIan Rogers''',
679329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers                         c_prefix=c_var(field_prefix), prefix=field_prefix,
689329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers                         c_name=c_var(argname), name=argname)
694f0d07c783afef89703dce32c94440fc8621a29bIan Rogers            push_indent()
704f0d07c783afef89703dce32c94440fc8621a29bIan Rogers
714f0d07c783afef89703dce32c94440fc8621a29bIan Rogers        if structured:
722a6c7b7c21adcd4493542604305585b852ccf554Mathieu Chartier            ret += generate_visit_struct_body(full_name, argname, argentry)
732a6c7b7c21adcd4493542604305585b852ccf554Mathieu Chartier        else:
74bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison            ret += mcgen('''
75bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allisonvisit_type_%(type)s(m, obj ? &(*obj)->%(c_prefix)s%(c_name)s : NULL, "%(name)s", &err);
76bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison''',
77bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison                         c_prefix=c_var(field_prefix), prefix=field_prefix,
78bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison                         type=type_name(argentry), c_name=c_var(argname),
79bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison                         name=argname)
809329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers
814f0d07c783afef89703dce32c94440fc8621a29bIan Rogers        if optional:
824f0d07c783afef89703dce32c94440fc8621a29bIan Rogers            pop_indent()
834f0d07c783afef89703dce32c94440fc8621a29bIan Rogers            ret += mcgen('''
842a6c7b7c21adcd4493542604305585b852ccf554Mathieu Chartier}
852a6c7b7c21adcd4493542604305585b852ccf554Mathieu Chartiervisit_end_optional(m, &err);
86bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison''')
87bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison
88bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    pop_indent()
89bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    ret += mcgen('''
90bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison
91bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    error_propagate(errp, err);
929329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers}
932a6c7b7c21adcd4493542604305585b852ccf554Mathieu Chartier''')
944f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    return ret
954f0d07c783afef89703dce32c94440fc8621a29bIan Rogers
964f0d07c783afef89703dce32c94440fc8621a29bIan Rogers
974f0d07c783afef89703dce32c94440fc8621a29bIan Rogersdef generate_visit_struct_body(field_prefix, name, members):
981984152ac92aad244ae15184d12f9ceade686b7bMathieu Chartier    ret = mcgen('''
994f0d07c783afef89703dce32c94440fc8621a29bIan Rogersif (!error_is_set(errp)) {
1004f0d07c783afef89703dce32c94440fc8621a29bIan Rogers''')
101dfcdf1a0d2d8d75b4c701317e4a092498a8d1e9eIan Rogers    push_indent()
1029329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers
1035d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    if not field_prefix:
1045d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao        full_name = name
1055d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    else:
1065d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao        full_name = "%s_%s" % (field_prefix, name)
1075d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao
1085d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    if len(field_prefix):
1095d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao        ret += mcgen('''
1105d9173014c1ca09f7249a6b07629aa37778b5f8fJeff HaoError **errp = &err; /* from outer scope */
1115d9173014c1ca09f7249a6b07629aa37778b5f8fJeff HaoError *err = NULL;
1125d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Haovisit_start_struct(m, NULL, "", "%(name)s", 0, &err);
113bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison''',
114dfcdf1a0d2d8d75b4c701317e4a092498a8d1e9eIan Rogers                name=name)
1159329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    else:
1169329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers        ret += mcgen('''
1174f0d07c783afef89703dce32c94440fc8621a29bIan RogersError *err = NULL;
1184f0d07c783afef89703dce32c94440fc8621a29bIan Rogersvisit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s), &err);
1194f0d07c783afef89703dce32c94440fc8621a29bIan Rogers''',
1202a6c7b7c21adcd4493542604305585b852ccf554Mathieu Chartier                name=name)
1212a6c7b7c21adcd4493542604305585b852ccf554Mathieu Chartier
122bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    ret += mcgen('''
123bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allisonif (!err) {
124bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    if (!obj || *obj) {
125bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison        visit_type_%(name)s_fields(m, obj, &err);
126bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison        error_propagate(errp, err);
127bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison        err = NULL;
128bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison    }
129bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison''',
130bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison        name=full_name)
1319329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers
13215fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers    pop_indent()
13315fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers    ret += mcgen('''
134637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers        /* Always call end_struct if start_struct succeeded.  */
135637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers        visit_end_struct(m, &err);
136637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    }
137637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    error_propagate(errp, err);
138637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers}
139637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers''')
140637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    return ret
141637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers
142637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogersdef generate_visit_struct(expr):
143637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers
144637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    name = expr['type']
145637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    members = expr['data']
146ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers    base = expr.get('base')
147ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers
148ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers    ret = generate_visit_struct_fields(name, "", "", members, base)
149ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers
150ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers    ret += mcgen('''
1519329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers
1529329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogersvoid visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp)
15357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers{
154ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers''',
155ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers                name=name)
156ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers
157ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers    push_indent()
158ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers    ret += generate_visit_struct_body("", name, members)
15957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    pop_indent()
16057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
1619329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    ret += mcgen('''
16257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers}
16357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers''')
16457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    return ret
16557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
1669329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogersdef generate_visit_list(name, members):
16757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    return mcgen('''
16857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
16957b86d47b66322693a070185fadfb43cb9c12eabIan Rogersvoid visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp)
17057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers{
1719329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    GenericList *i, **prev = (GenericList **)obj;
17257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    Error *err = NULL;
17357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
17457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    if (!error_is_set(errp)) {
17557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        visit_start_list(m, name, &err);
176a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers        if (!err) {
1779329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
17857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                %(name)sList *native_i = (%(name)sList *)i;
17957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                visit_type_%(name)s(m, &native_i->value, NULL, &err);
18057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers            }
18157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers            error_propagate(errp, err);
1829329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers            err = NULL;
18357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
18457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers            /* Always call end_list if start_list succeeded.  */
18557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers            visit_end_list(m, &err);
18657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        }
187a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers        error_propagate(errp, err);
1889329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    }
18957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers}
19057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers''',
19144b412bb795fa6999129b2bc16f5eec1ea97e8f8buzbee                name=name)
19257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
19357b86d47b66322693a070185fadfb43cb9c12eabIan Rogersdef generate_visit_enum(name, members):
19444b412bb795fa6999129b2bc16f5eec1ea97e8f8buzbee    return mcgen('''
195468532ea115657709bc32ee498e701a4c71762d4Ian Rogers
19644b412bb795fa6999129b2bc16f5eec1ea97e8f8buzbeevoid visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **errp)
1976f495f2898a418f87e2a919e04fe23521bb0b9e9Brian Carlstrom{
19857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    visit_type_enum(m, (int *)obj, %(name)s_lookup, "%(name)s", name, errp);
1996f495f2898a418f87e2a919e04fe23521bb0b9e9Brian Carlstrom}
200468532ea115657709bc32ee498e701a4c71762d4Ian Rogers''',
2016f495f2898a418f87e2a919e04fe23521bb0b9e9Brian Carlstrom                 name=name)
202bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
20357b86d47b66322693a070185fadfb43cb9c12eabIan Rogersdef generate_visit_anon_union(name, members):
204bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    ret = mcgen('''
205468532ea115657709bc32ee498e701a4c71762d4Ian Rogers
2069651f425f7413772a7b5352da2b04eb7de7d416fIan Rogersvoid visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp)
2079651f425f7413772a7b5352da2b04eb7de7d416fIan Rogers{
20857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    Error *err = NULL;
20957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
2109651f425f7413772a7b5352da2b04eb7de7d416fIan Rogers    if (!error_is_set(errp)) {
211468532ea115657709bc32ee498e701a4c71762d4Ian Rogers        visit_start_implicit_struct(m, (void**) obj, sizeof(%(name)s), &err);
2129651f425f7413772a7b5352da2b04eb7de7d416fIan Rogers        visit_get_next_type(m, (int*) &(*obj)->kind, %(name)s_qtypes, name, &err);
2139651f425f7413772a7b5352da2b04eb7de7d416fIan Rogers        switch ((*obj)->kind) {
21457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers''',
2159651f425f7413772a7b5352da2b04eb7de7d416fIan Rogers    name=name)
216468532ea115657709bc32ee498e701a4c71762d4Ian Rogers
2179651f425f7413772a7b5352da2b04eb7de7d416fIan Rogers    for key in members:
2189651f425f7413772a7b5352da2b04eb7de7d416fIan Rogers        assert (members[key] in builtin_types
21957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers            or find_struct(members[key])
2209651f425f7413772a7b5352da2b04eb7de7d416fIan Rogers            or find_union(members[key])), "Invalid anonymous union member"
221468532ea115657709bc32ee498e701a4c71762d4Ian Rogers
22257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        ret += mcgen('''
22357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        case %(abbrev)s_KIND_%(enum)s:
224c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers            visit_type_%(c_type)s(m, &(*obj)->%(c_name)s, name, &err);
225c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers            break;
226c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers''',
227c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers                abbrev = de_camel_case(name).upper(),
228634eb2eb14f87753519d0ef2c5f256e55888f378Elliott Hughes                enum = c_fun(de_camel_case(key),False).upper(),
2294a3164faefd255b1c1e911e7ad7c3d57749caaf6buzbee                c_type = type_name(members[key]),
230c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers                c_name = c_fun(key))
231c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers
2324a3164faefd255b1c1e911e7ad7c3d57749caaf6buzbee    ret += mcgen('''
233c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers        default:
234c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers            abort();
2354a3164faefd255b1c1e911e7ad7c3d57749caaf6buzbee        }
236ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers        error_propagate(errp, err);
237ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers        err = NULL;
2384a3164faefd255b1c1e911e7ad7c3d57749caaf6buzbee        visit_end_implicit_struct(m, &err);
239c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    }
240c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers}
2419329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers''')
2424f0d07c783afef89703dce32c94440fc8621a29bIan Rogers
243c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    return ret
244c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers
245865e6e01486e3d7d61b7d0d952b420e5912c8219buzbee
246865e6e01486e3d7d61b7d0d952b420e5912c8219buzbeedef generate_visit_union(expr):
2479329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers
2489329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    name = expr['union']
249c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers    members = expr['data']
250865e6e01486e3d7d61b7d0d952b420e5912c8219buzbee
2519329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    base = expr.get('base')
252634eb2eb14f87753519d0ef2c5f256e55888f378Elliott Hughes    discriminator = expr.get('discriminator')
253a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers
254637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    if discriminator == {}:
255637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers        assert not base
256637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers        return generate_visit_anon_union(name, members)
257a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers
2589329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    ret = generate_visit_enum('%sKind' % name, members.keys())
259c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers
260a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers    if base:
2618dbb708c7dc05c786329eb5c3fff3194ab6472acLogan Chien        base_fields = find_struct(base)['data']
2628dbb708c7dc05c786329eb5c3fff3194ab6472acLogan Chien        if discriminator:
263a32a6fd4a781262dff4fec102da053d16b7ef6c0Ian Rogers            base_fields = base_fields.copy()
2648dbb708c7dc05c786329eb5c3fff3194ab6472acLogan Chien            del base_fields[discriminator]
2658dbb708c7dc05c786329eb5c3fff3194ab6472acLogan Chien        ret += generate_visit_struct_fields(name, "", "", base_fields)
2668dbb708c7dc05c786329eb5c3fff3194ab6472acLogan Chien
2678dbb708c7dc05c786329eb5c3fff3194ab6472acLogan Chien    ret += mcgen('''
268ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers
26957b86d47b66322693a070185fadfb43cb9c12eabIan Rogersvoid visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp)
2706474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao{
2716474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao    Error *err = NULL;
2726474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao
2736474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao    if (!error_is_set(errp)) {
2746474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao        visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s), &err);
2756474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao        if (!err) {
2766474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao            if (obj && *obj) {
2770177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers''',
2785d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao                 name=name)
2795d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao
2805d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao
2815d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    push_indent()
2825d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    push_indent()
2835d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    push_indent()
2845d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao
2855d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    if base:
2865d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao        ret += mcgen('''
2875d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    visit_type_%(name)s_fields(m, obj, &err);
2885d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao''',
2895d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao            name=name)
2905d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao
2915d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    pop_indent()
2925d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao
2935d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    if not discriminator:
2945d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao        desc_type = "type"
2956474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao    else:
2965d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao        desc_type = discriminator
2975d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    ret += mcgen('''
2985d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao        visit_type_%(name)sKind(m, &(*obj)->kind, "%(type)s", &err);
2995d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao        if (!err) {
3005d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao            switch ((*obj)->kind) {
3015d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao''',
3025d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao                 name=name, type=desc_type)
3035d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao
3045d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    for key in members:
305ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers        if not discriminator:
3065d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao            fmt = 'visit_type_%(c_type)s(m, &(*obj)->%(c_name)s, "data", &err);'
3076474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao        else:
3085d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao            fmt = '''visit_start_implicit_struct(m, (void**) &(*obj)->%(c_name)s, sizeof(%(c_type)s), &err);
3095d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao                if (!err) {
3105d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao                    visit_type_%(c_type)s_fields(m, &(*obj)->%(c_name)s, &err);
311bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison                    error_propagate(errp, err);
312bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison                    err = NULL;
313bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison                    visit_end_implicit_struct(m, &err);
314bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison                }'''
315bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison
3165d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao        ret += mcgen('''
3175d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao            case %(abbrev)s_KIND_%(enum)s:
3185d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao                ''' + fmt + '''
3196474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao                break;
3205d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao''',
32157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                abbrev = de_camel_case(name).upper(),
32257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                enum = c_fun(de_camel_case(key),False).upper(),
323637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers                c_type=type_name(members[key]),
32457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                c_name=c_fun(key))
32557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
32657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    ret += mcgen('''
32757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers            default:
32857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers                abort();
32957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers            }
33057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        }
3319329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers        error_propagate(errp, err);
33257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers        err = NULL;
33360db5ab3a2e480db9236325a14cb5a867881d8bbIan Rogers    }
334ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers''')
335ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers    pop_indent()
336ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers    ret += mcgen('''
3379329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers        /* Always call end_struct if start_struct succeeded.  */
338468532ea115657709bc32ee498e701a4c71762d4Ian Rogers        visit_end_struct(m, &err);
3394f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    }
3404f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    error_propagate(errp, err);
3414f0d07c783afef89703dce32c94440fc8621a29bIan Rogers}
342af778e627aa41ec6c176cba537062b95d4d960b6Elliott Hughes''')
3434f0d07c783afef89703dce32c94440fc8621a29bIan Rogers
344637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    pop_indent();
345ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers    ret += mcgen('''
346468532ea115657709bc32ee498e701a4c71762d4Ian Rogers}
3474f0d07c783afef89703dce32c94440fc8621a29bIan Rogers''')
3484f0d07c783afef89703dce32c94440fc8621a29bIan Rogers
349d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers    return ret
350d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers
3514f0d07c783afef89703dce32c94440fc8621a29bIan Rogersdef generate_declaration(name, members, genlist=True, builtin_type=False):
3529329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers    ret = ""
353468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    if not builtin_type:
3545d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers        ret += mcgen('''
3555d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers
3564e6a31eb97f22f4480827474b30b9e64f396eaceMathieu Chartiervoid visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp);
357ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier''',
3585d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers                    name=name)
359d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers
360d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers    if genlist:
3615d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers        ret += mcgen('''
362b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogersvoid visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp);
363d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers''',
3645d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers                 name=name)
3655d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers
3665d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    return ret
367ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier
3685d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogersdef generate_enum_declaration(name, members, genlist=True):
369d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers    ret = ""
370d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers    if genlist:
3715d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers        ret += mcgen('''
372d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersvoid visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp);
373ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier''',
374ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier                     name=name)
3755d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers
376d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers    return ret
377d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers
3785d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogersdef generate_decl_enum(name, members, genlist=True):
3794f0d07c783afef89703dce32c94440fc8621a29bIan Rogers    return mcgen('''
3804f0d07c783afef89703dce32c94440fc8621a29bIan Rogers
3814f0d07c783afef89703dce32c94440fc8621a29bIan Rogersvoid visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **errp);
3824f0d07c783afef89703dce32c94440fc8621a29bIan Rogers''',
383d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers                name=name)
384d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers
385d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogerstry:
386468532ea115657709bc32ee498e701a4c71762d4Ian Rogers    opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:o:",
387ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers                                   ["source", "header", "builtins", "prefix=",
388ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers                                    "output-dir="])
389ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogersexcept getopt.GetoptError, err:
390d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers    print str(err)
391ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers    sys.exit(1)
3929329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers
393468532ea115657709bc32ee498e701a4c71762d4Ian Rogersoutput_dir = ""
3945d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogersprefix = ""
395d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersc_file = 'qapi-visit.c'
396ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartierh_file = 'qapi-visit.h'
3975d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers
398d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersdo_c = False
399d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersdo_h = False
400d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersdo_builtins = False
4015d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers
402d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersfor o, a in opts:
4035d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    if o in ("-p", "--prefix"):
404d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers        prefix = a
405d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers    elif o in ("-o", "--output-dir"):
406b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers        output_dir = a + "/"
407d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers    elif o in ("-c", "--source"):
4085d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers        do_c = True
409d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers    elif o in ("-h", "--header"):
410d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers        do_h = True
411d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers    elif o in ("-b", "--builtins"):
4125d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers        do_builtins = True
4134f0d07c783afef89703dce32c94440fc8621a29bIan Rogers
414637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogersif not do_c and not do_h:
415637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    do_c = True
416637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers    do_h = True
4174f0d07c783afef89703dce32c94440fc8621a29bIan Rogers
418637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogersc_file = output_dir + prefix + c_file
419ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogersh_file = output_dir + prefix + h_file
420468532ea115657709bc32ee498e701a4c71762d4Ian Rogers
421ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogerstry:
422ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers    os.makedirs(output_dir)
423a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogersexcept os.error, e:
424a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    if e.errno != errno.EEXIST:
425ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers        raise
426a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers
427468532ea115657709bc32ee498e701a4c71762d4Ian Rogersdef maybe_open(really, name, opt):
428a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    if really:
429a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers        return open(name, opt)
430a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    else:
431a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers        import StringIO
432a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers        return StringIO.StringIO()
433a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers
434a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogersfdef = maybe_open(do_c, c_file, 'w')
435a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogersfdecl = maybe_open(do_h, h_file, 'w')
436a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers
437a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogersfdef.write(mcgen('''
4385d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
439a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers
440a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers/*
441a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers * schema-defined QAPI visitor functions
4425d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers *
443a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers * Copyright IBM, Corp. 2011
444a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers *
445a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers * Authors:
446bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison *  Anthony Liguori   <aliguori@us.ibm.com>
447bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison *
448a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
449a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers * See the COPYING.LIB file in the top-level directory.
450a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers *
451a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers */
452a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers
453468532ea115657709bc32ee498e701a4c71762d4Ian Rogers#include "qemu-common.h"
454e51a511ccee3f3c0120807321bcc160fcaa664beIan Rogers#include "%(header)s"
455e51a511ccee3f3c0120807321bcc160fcaa664beIan Rogers''',
456a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers                 header=basename(h_file)))
457a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers
458a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogersfdecl.write(mcgen('''
459e51a511ccee3f3c0120807321bcc160fcaa664beIan Rogers/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
460a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers
461a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers/*
462a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers * schema-defined QAPI visitor function
463a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers *
464a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers * Copyright IBM, Corp. 2011
465a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers *
466a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers * Authors:
467a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers *  Anthony Liguori   <aliguori@us.ibm.com>
468a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers *
469a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
470a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers * See the COPYING.LIB file in the top-level directory.
471a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers *
472a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers */
473a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers
474a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers#ifndef %(guard)s
475a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers#define %(guard)s
4765d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers
477a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers#include "qapi/visitor.h"
478a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers#include "%(prefix)sqapi-types.h"
479a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers
480a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers''',
4815d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers                  prefix=prefix, guard=guardname(h_file)))
4825d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers
483a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogersexprs = parse_schema(sys.stdin)
484a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers
485a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers# to avoid header dependency hell, we always generate declarations
486a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers# for built-in types in our header files and simply guard them
487a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogersfdecl.write(guardstart("QAPI_VISIT_BUILTIN_VISITOR_DECL"))
488a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogersfor typename in builtin_types:
4895d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    fdecl.write(generate_declaration(typename, None, genlist=True,
490a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers                                     builtin_type=True))
491a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogersfdecl.write(guardend("QAPI_VISIT_BUILTIN_VISITOR_DECL"))
492a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers
4935d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers# ...this doesn't work for cases where we link in multiple objects that
4945d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers# have the functions defined, so we use -b option to provide control
495a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers# over these cases
496a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogersif do_builtins:
497a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    fdef.write(guardstart("QAPI_VISIT_BUILTIN_VISITOR_DEF"))
4985d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers    for typename in builtin_types:
499a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers        fdef.write(generate_visit_list(typename, None))
500a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    fdef.write(guardend("QAPI_VISIT_BUILTIN_VISITOR_DEF"))
501a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers
502a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogersfor expr in exprs:
503a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    if expr.has_key('type'):
504a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers        ret = generate_visit_struct(expr)
505a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers        ret += generate_visit_list(expr['type'], expr['data'])
5065d885c82522f9f3f0775a6255b64bcd08c2a4c9eIan Rogers        fdef.write(ret)
507a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers
508a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers        ret = generate_declaration(expr['type'], expr['data'])
509a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers        fdecl.write(ret)
510a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    elif expr.has_key('union'):
511a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers        ret = generate_visit_union(expr)
512a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers        ret += generate_visit_list(expr['union'], expr['data'])
513a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers        fdef.write(ret)
514a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers
515cbba6ac9bf9a6c630a7aafae6d8767b5ddbb6fd5Ian Rogers        ret = generate_decl_enum('%sKind' % expr['union'], expr['data'].keys())
516cbba6ac9bf9a6c630a7aafae6d8767b5ddbb6fd5Ian Rogers        ret += generate_declaration(expr['union'], expr['data'])
517cbba6ac9bf9a6c630a7aafae6d8767b5ddbb6fd5Ian Rogers        fdecl.write(ret)
518cbba6ac9bf9a6c630a7aafae6d8767b5ddbb6fd5Ian Rogers    elif expr.has_key('enum'):
519cbba6ac9bf9a6c630a7aafae6d8767b5ddbb6fd5Ian Rogers        ret = generate_visit_list(expr['enum'], expr['data'])
520cbba6ac9bf9a6c630a7aafae6d8767b5ddbb6fd5Ian Rogers        ret += generate_visit_enum(expr['enum'], expr['data'])
5219329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers        fdef.write(ret)
522468532ea115657709bc32ee498e701a4c71762d4Ian Rogers
5234f0d07c783afef89703dce32c94440fc8621a29bIan Rogers        ret = generate_decl_enum(expr['enum'], expr['data'])
5244f0d07c783afef89703dce32c94440fc8621a29bIan Rogers        ret += generate_enum_declaration(expr['enum'], expr['data'])
5254f0d07c783afef89703dce32c94440fc8621a29bIan Rogers        fdecl.write(ret)
526aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom
5274f0d07c783afef89703dce32c94440fc8621a29bIan Rogersfdecl.write('''
5284f0d07c783afef89703dce32c94440fc8621a29bIan Rogers#endif
529637859cef76e7d41f7fdfd1f1aea7d60b4a315dcIan Rogers''')
530ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogers
531468532ea115657709bc32ee498e701a4c71762d4Ian Rogersfdecl.flush()
532ce9eca6de042f26e9eebc41c9bee8b4d14f753aaIan Rogersfdecl.close()
53328ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogers
53428ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogersfdef.flush()
53528ad40dc3ec2f09b0ffd4f6d6787bf1b532ccd5dIan Rogersfdef.close()
5369329bbb44d19866a70c6f2ff1657eafe399c5bf5Ian Rogers