1910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#
2910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner# QAPI types generator
3910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#
4910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner# Copyright IBM, Corp. 2011
5910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#
6910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner# Authors:
7910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#  Anthony Liguori <aliguori@us.ibm.com>
8910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#
9910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner# This work is licensed under the terms of the GNU GPLv2.
10910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner# See the COPYING.LIB file in the top-level directory.
11910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
12910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerfrom ordereddict import OrderedDict
13910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerfrom qapi import *
14910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerimport sys
15910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerimport os
16910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerimport getopt
17910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerimport errno
18910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
19910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerdef generate_fwd_struct(name, members, builtin_type=False):
20910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    if builtin_type:
21910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        return mcgen('''
22910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
23910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnertypedef struct %(name)sList
24910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{
25910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    union {
26910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        %(type)s value;
27910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        uint64_t padding;
28910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    };
29910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    struct %(name)sList *next;
30910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} %(name)sList;
31910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''',
32910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner                     type=c_type(name),
33910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner                     name=name)
34910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
35910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    return mcgen('''
36910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
37910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnertypedef struct %(name)s %(name)s;
38910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
39910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnertypedef struct %(name)sList
40910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{
41910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    union {
42910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        %(name)s *value;
43910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        uint64_t padding;
44910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    };
45910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    struct %(name)sList *next;
46910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} %(name)sList;
47910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''',
48910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner                 name=name)
49910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
50910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerdef generate_fwd_enum_struct(name, members):
51910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    return mcgen('''
52910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnertypedef struct %(name)sList
53910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{
54910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    union {
55910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        %(name)s value;
56910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        uint64_t padding;
57910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    };
58910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    struct %(name)sList *next;
59910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} %(name)sList;
60910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''',
61910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner                 name=name)
62910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
63910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerdef generate_struct_fields(members):
64910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    ret = ''
65910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
66910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    for argname, argentry, optional, structured in parse_args(members):
67910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        if optional:
68910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            ret += mcgen('''
69910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    bool has_%(c_name)s;
70910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''',
71910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner                         c_name=c_var(argname))
72910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        if structured:
73910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            push_indent()
74910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            ret += generate_struct({ "field": argname, "data": argentry})
75910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            pop_indent()
76910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        else:
77910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            ret += mcgen('''
78910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    %(c_type)s %(c_name)s;
79910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''',
80910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner                     c_type=c_type(argentry), c_name=c_var(argname))
81910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
82910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    return ret
83910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
84910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerdef generate_struct(expr):
85910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
86910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    structname = expr.get('type', "")
87910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    fieldname = expr.get('field', "")
88910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    members = expr['data']
89910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    base = expr.get('base')
90910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
91910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    ret = mcgen('''
92910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstruct %(name)s
93910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{
94910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''',
95910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner          name=structname)
96910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
97910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    if base:
98910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        ret += generate_struct_fields({'base': base})
99910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
100910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    ret += generate_struct_fields(members)
101910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
102910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    if len(fieldname):
103910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        fieldname = " " + fieldname
104910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    ret += mcgen('''
105910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner}%(field)s;
106910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''',
107910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            field=fieldname)
108910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
109910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    return ret
110910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
111910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerdef generate_enum_lookup(name, values):
112910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    ret = mcgen('''
113910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerconst char *%(name)s_lookup[] = {
114910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''',
115910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner                         name=name)
116910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    i = 0
117910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    for value in values:
118910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        ret += mcgen('''
119910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    "%(value)s",
120910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''',
121910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner                     value=value)
122910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
123910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    ret += mcgen('''
124910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    NULL,
125910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner};
126910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
127910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''')
128910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    return ret
129910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
130910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerdef generate_enum_name(name):
131910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    if name.isupper():
132910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        return c_fun(name, False)
133910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    new_name = ''
134910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    for c in c_fun(name, False):
135910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        if c.isupper():
136910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            new_name += '_'
137910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        new_name += c
138910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    return new_name.lstrip('_').upper()
139910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
140910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerdef generate_enum(name, values):
141910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    lookup_decl = mcgen('''
142910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerextern const char *%(name)s_lookup[];
143910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''',
144910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner                name=name)
145910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
146910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    enum_decl = mcgen('''
147910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnertypedef enum %(name)s
148910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{
149910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''',
150910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner                name=name)
151910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
152910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    # append automatically generated _MAX value
153910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    enum_values = values + [ 'MAX' ]
154910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
155910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    i = 0
156910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    for value in enum_values:
157910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        enum_decl += mcgen('''
158910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    %(abbrev)s_%(value)s = %(i)d,
159910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''',
160910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner                     abbrev=de_camel_case(name).upper(),
161910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner                     value=generate_enum_name(value),
162910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner                     i=i)
163910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        i += 1
164910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
165910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    enum_decl += mcgen('''
166910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner} %(name)s;
167910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''',
168910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner                 name=name)
169910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
170910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    return lookup_decl + enum_decl
171910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
172910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerdef generate_anon_union_qtypes(expr):
173910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
174910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    name = expr['union']
175910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    members = expr['data']
176910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
177910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    ret = mcgen('''
178910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerconst int %(name)s_qtypes[QTYPE_MAX] = {
179910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''',
180910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    name=name)
181910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
182910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    for key in members:
183910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        qapi_type = members[key]
184910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        if builtin_type_qtypes.has_key(qapi_type):
185910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            qtype = builtin_type_qtypes[qapi_type]
186910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        elif find_struct(qapi_type):
187910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            qtype = "QTYPE_QDICT"
188910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        elif find_union(qapi_type):
189910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            qtype = "QTYPE_QDICT"
190910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        else:
191910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            assert False, "Invalid anonymous union member"
192910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
193910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        ret += mcgen('''
194910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    [ %(qtype)s ] = %(abbrev)s_KIND_%(enum)s,
195910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''',
196910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        qtype = qtype,
197910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        abbrev = de_camel_case(name).upper(),
198910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        enum = c_fun(de_camel_case(key),False).upper())
199910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
200910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    ret += mcgen('''
201910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner};
202910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''')
203910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    return ret
204910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
205910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
206910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerdef generate_union(expr):
207910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
208910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    name = expr['union']
209910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    typeinfo = expr['data']
210910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
211910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    base = expr.get('base')
212910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    discriminator = expr.get('discriminator')
213910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
214910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    ret = mcgen('''
215910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstruct %(name)s
216910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{
217910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    %(name)sKind kind;
218910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    union {
219910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        void *data;
220910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''',
221910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner                name=name)
222910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
223910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    for key in typeinfo:
224910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        ret += mcgen('''
225910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        %(c_type)s %(c_name)s;
226910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''',
227910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner                     c_type=c_type(typeinfo[key]),
228910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner                     c_name=c_fun(key))
229910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
230910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    ret += mcgen('''
231910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    };
232910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''')
233910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
234910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    if base:
235910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        base_fields = find_struct(base)['data']
236910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        if discriminator:
237910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            base_fields = base_fields.copy()
238910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            del base_fields[discriminator]
239910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        ret += generate_struct_fields(base_fields)
240910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    else:
241910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        assert not discriminator
242910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
243910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    ret += mcgen('''
244910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner};
245910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''')
246910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    if discriminator == {}:
247910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        ret += mcgen('''
248910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerextern const int %(name)s_qtypes[];
249910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''',
250910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            name=name)
251910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
252910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
253910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    return ret
254910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
255910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerdef generate_type_cleanup_decl(name):
256910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    ret = mcgen('''
257910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid qapi_free_%(type)s(%(c_type)s obj);
258910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''',
259910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner                c_type=c_type(name),type=name)
260910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    return ret
261910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
262910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerdef generate_type_cleanup(name):
263910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    ret = mcgen('''
264910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
265910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid qapi_free_%(type)s(%(c_type)s obj)
266910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{
267910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    QapiDeallocVisitor *md;
268910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    Visitor *v;
269910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
270910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    if (!obj) {
271910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        return;
272910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    }
273910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
274910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    md = qapi_dealloc_visitor_new();
275910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    v = qapi_dealloc_get_visitor(md);
276910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    visit_type_%(type)s(v, &obj, NULL, NULL);
277910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    qapi_dealloc_visitor_cleanup(md);
278910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner}
279910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''',
280910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner                c_type=c_type(name),type=name)
281910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    return ret
282910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
283910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
284910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnertry:
285910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:o:",
286910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner                                   ["source", "header", "builtins",
287910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner                                    "prefix=", "output-dir="])
288910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerexcept getopt.GetoptError, err:
289910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    print str(err)
290910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    sys.exit(1)
291910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
292910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turneroutput_dir = ""
293910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerprefix = ""
294910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerc_file = 'qapi-types.c'
295910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerh_file = 'qapi-types.h'
296910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
297910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerdo_c = False
298910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerdo_h = False
299910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerdo_builtins = False
300910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
301910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerfor o, a in opts:
302910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    if o in ("-p", "--prefix"):
303910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        prefix = a
304910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    elif o in ("-o", "--output-dir"):
305910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        output_dir = a + "/"
306910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    elif o in ("-c", "--source"):
307910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        do_c = True
308910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    elif o in ("-h", "--header"):
309910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        do_h = True
310910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    elif o in ("-b", "--builtins"):
311910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        do_builtins = True
312910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
313910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerif not do_c and not do_h:
314910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    do_c = True
315910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    do_h = True
316910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
317910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerc_file = output_dir + prefix + c_file
318910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerh_file = output_dir + prefix + h_file
319910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
320910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnertry:
321910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    os.makedirs(output_dir)
322910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerexcept os.error, e:
323910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    if e.errno != errno.EEXIST:
324910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        raise
325910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
326910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerdef maybe_open(really, name, opt):
327910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    if really:
328910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        return open(name, opt)
329910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    else:
330910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        import StringIO
331910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        return StringIO.StringIO()
332910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
333910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerfdef = maybe_open(do_c, c_file, 'w')
334910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerfdecl = maybe_open(do_h, h_file, 'w')
335910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
336910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerfdef.write(mcgen('''
337910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
338910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
339910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner/*
340910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner * deallocation functions for schema-defined QAPI types
341910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner *
342910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner * Copyright IBM, Corp. 2011
343910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner *
344910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner * Authors:
345910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner *  Anthony Liguori   <aliguori@us.ibm.com>
346910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner *  Michael Roth      <mdroth@linux.vnet.ibm.com>
347910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner *
348910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
349910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner * See the COPYING.LIB file in the top-level directory.
350910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner *
351910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner */
352910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
353910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#include "qapi/dealloc-visitor.h"
354910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#include "%(prefix)sqapi-types.h"
355910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#include "%(prefix)sqapi-visit.h"
356910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
357910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''',             prefix=prefix))
358910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
359910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerfdecl.write(mcgen('''
360910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
361910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
362910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner/*
363910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner * schema-defined QAPI types
364910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner *
365910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner * Copyright IBM, Corp. 2011
366910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner *
367910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner * Authors:
368910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner *  Anthony Liguori   <aliguori@us.ibm.com>
369910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner *
370910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
371910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner * See the COPYING.LIB file in the top-level directory.
372910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner *
373910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner */
374910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
375910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#ifndef %(guard)s
376910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#define %(guard)s
377910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
378910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#include <stdbool.h>
379910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#include <stdint.h>
380910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
381910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''',
382910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner                  guard=guardname(h_file)))
383910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
384910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerexprs = parse_schema(sys.stdin)
385910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerexprs = filter(lambda expr: not expr.has_key('gen'), exprs)
386910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
387910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerfdecl.write(guardstart("QAPI_TYPES_BUILTIN_STRUCT_DECL"))
388910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerfor typename in builtin_types:
389910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    fdecl.write(generate_fwd_struct(typename, None, builtin_type=True))
390910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerfdecl.write(guardend("QAPI_TYPES_BUILTIN_STRUCT_DECL"))
391910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
392910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerfor expr in exprs:
393910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    ret = "\n"
394910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    if expr.has_key('type'):
395910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        ret += generate_fwd_struct(expr['type'], expr['data'])
396910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    elif expr.has_key('enum'):
397910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        ret += generate_enum(expr['enum'], expr['data']) + "\n"
398910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        ret += generate_fwd_enum_struct(expr['enum'], expr['data'])
399910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        fdef.write(generate_enum_lookup(expr['enum'], expr['data']))
400910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    elif expr.has_key('union'):
401910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        ret += generate_fwd_struct(expr['union'], expr['data']) + "\n"
402910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        ret += generate_enum('%sKind' % expr['union'], expr['data'].keys())
403910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        fdef.write(generate_enum_lookup('%sKind' % expr['union'], expr['data'].keys()))
404910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        if expr.get('discriminator') == {}:
405910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            fdef.write(generate_anon_union_qtypes(expr))
406910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    else:
407910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        continue
408910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    fdecl.write(ret)
409910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
410910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner# to avoid header dependency hell, we always generate declarations
411910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner# for built-in types in our header files and simply guard them
412910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerfdecl.write(guardstart("QAPI_TYPES_BUILTIN_CLEANUP_DECL"))
413910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerfor typename in builtin_types:
414910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    fdecl.write(generate_type_cleanup_decl(typename + "List"))
415910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerfdecl.write(guardend("QAPI_TYPES_BUILTIN_CLEANUP_DECL"))
416910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
417910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner# ...this doesn't work for cases where we link in multiple objects that
418910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner# have the functions defined, so we use -b option to provide control
419910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner# over these cases
420910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerif do_builtins:
421910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    fdef.write(guardstart("QAPI_TYPES_BUILTIN_CLEANUP_DEF"))
422910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    for typename in builtin_types:
423910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        fdef.write(generate_type_cleanup(typename + "List"))
424910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    fdef.write(guardend("QAPI_TYPES_BUILTIN_CLEANUP_DEF"))
425910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
426910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerfor expr in exprs:
427910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    ret = "\n"
428910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    if expr.has_key('type'):
429910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        ret += generate_struct(expr) + "\n"
430910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        ret += generate_type_cleanup_decl(expr['type'] + "List")
431910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        fdef.write(generate_type_cleanup(expr['type'] + "List") + "\n")
432910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        ret += generate_type_cleanup_decl(expr['type'])
433910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        fdef.write(generate_type_cleanup(expr['type']) + "\n")
434910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    elif expr.has_key('union'):
435910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        ret += generate_union(expr)
436910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        ret += generate_type_cleanup_decl(expr['union'] + "List")
437910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        fdef.write(generate_type_cleanup(expr['union'] + "List") + "\n")
438910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        ret += generate_type_cleanup_decl(expr['union'])
439910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        fdef.write(generate_type_cleanup(expr['union']) + "\n")
440910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    elif expr.has_key('enum'):
441910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        ret += generate_type_cleanup_decl(expr['enum'] + "List")
442910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        fdef.write(generate_type_cleanup(expr['enum'] + "List") + "\n")
443910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    else:
444910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        continue
445910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    fdecl.write(ret)
446910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
447910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerfdecl.write('''
448910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner#endif
449910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner''')
450910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
451910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerfdecl.flush()
452910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerfdecl.close()
453910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
454910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerfdef.flush()
455910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerfdef.close()
456