Annotation of qemu/scripts/qapi-commands.py, revision 1.1.1.1

1.1       root        1: #
                      2: # QAPI command marshaller generator
                      3: #
                      4: # Copyright IBM, Corp. 2011
                      5: #
                      6: # Authors:
                      7: #  Anthony Liguori <[email protected]>
                      8: #  Michael Roth    <[email protected]>
                      9: #
                     10: # This work is licensed under the terms of the GNU GPLv2.
                     11: # See the COPYING.LIB file in the top-level directory.
                     12: 
                     13: from ordereddict import OrderedDict
                     14: from qapi import *
                     15: import sys
                     16: import os
                     17: import getopt
                     18: import errno
                     19: 
                     20: def generate_decl_enum(name, members, genlist=True):
                     21:     return mcgen('''
                     22: 
                     23: void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **errp);
                     24: ''',
                     25:                 name=name)
                     26: 
                     27: def generate_command_decl(name, args, ret_type):
                     28:     arglist=""
                     29:     for argname, argtype, optional, structured in parse_args(args):
                     30:         argtype = c_type(argtype)
                     31:         if argtype == "char *":
                     32:             argtype = "const char *"
                     33:         if optional:
                     34:             arglist += "bool has_%s, " % c_var(argname)
                     35:         arglist += "%s %s, " % (argtype, c_var(argname))
                     36:     return mcgen('''
                     37: %(ret_type)s qmp_%(name)s(%(args)sError **errp);
                     38: ''',
                     39:                  ret_type=c_type(ret_type), name=c_var(name), args=arglist).strip()
                     40: 
                     41: def gen_sync_call(name, args, ret_type, indent=0):
                     42:     ret = ""
                     43:     arglist=""
                     44:     retval=""
                     45:     if ret_type:
                     46:         retval = "retval = "
                     47:     for argname, argtype, optional, structured in parse_args(args):
                     48:         if optional:
                     49:             arglist += "has_%s, " % c_var(argname)
                     50:         arglist += "%s, " % (c_var(argname))
                     51:     push_indent(indent)
                     52:     ret = mcgen('''
                     53: %(retval)sqmp_%(name)s(%(args)serrp);
                     54: 
                     55: ''',
                     56:                 name=c_var(name), args=arglist, retval=retval).rstrip()
                     57:     if ret_type:
                     58:         ret += "\n" + mcgen(''''
                     59: %(marshal_output_call)s
                     60: ''',
                     61:                             marshal_output_call=gen_marshal_output_call(name, ret_type)).rstrip()
                     62:     pop_indent(indent)
                     63:     return ret.rstrip()
                     64: 
                     65: 
                     66: def gen_marshal_output_call(name, ret_type):
                     67:     if not ret_type:
                     68:         return ""
                     69:     return "qmp_marshal_output_%s(retval, ret, errp);" % c_var(name)
                     70: 
                     71: def gen_visitor_output_containers_decl(ret_type):
                     72:     ret = ""
                     73:     push_indent()
                     74:     if ret_type:
                     75:         ret += mcgen('''
                     76: QmpOutputVisitor *mo;
                     77: QapiDeallocVisitor *md;
                     78: Visitor *v;
                     79: ''')
                     80:     pop_indent()
                     81: 
                     82:     return ret
                     83: 
                     84: def gen_visitor_input_containers_decl(args):
                     85:     ret = ""
                     86: 
                     87:     push_indent()
                     88:     if len(args) > 0:
                     89:         ret += mcgen('''
                     90: QmpInputVisitor *mi;
                     91: QapiDeallocVisitor *md;
                     92: Visitor *v;
                     93: ''')
                     94:     pop_indent()
                     95: 
                     96:     return ret.rstrip()
                     97: 
                     98: def gen_visitor_input_vars_decl(args):
                     99:     ret = ""
                    100:     push_indent()
                    101:     for argname, argtype, optional, structured in parse_args(args):
                    102:         if optional:
                    103:             ret += mcgen('''
                    104: bool has_%(argname)s = false;
                    105: ''',
                    106:                          argname=c_var(argname))
                    107:         if c_type(argtype).endswith("*"):
                    108:             ret += mcgen('''
                    109: %(argtype)s %(argname)s = NULL;
                    110: ''',
                    111:                          argname=c_var(argname), argtype=c_type(argtype))
                    112:         else:
                    113:             ret += mcgen('''
                    114: %(argtype)s %(argname)s;
                    115: ''',
                    116:                          argname=c_var(argname), argtype=c_type(argtype))
                    117: 
                    118:     pop_indent()
                    119:     return ret.rstrip()
                    120: 
                    121: def gen_visitor_input_block(args, obj, dealloc=False):
                    122:     ret = ""
                    123:     if len(args) == 0:
                    124:         return ret
                    125: 
                    126:     push_indent()
                    127: 
                    128:     if dealloc:
                    129:         ret += mcgen('''
                    130: md = qapi_dealloc_visitor_new();
                    131: v = qapi_dealloc_get_visitor(md);
                    132: ''')
                    133:     else:
                    134:         ret += mcgen('''
                    135: mi = qmp_input_visitor_new(%(obj)s);
                    136: v = qmp_input_get_visitor(mi);
                    137: ''',
                    138:                      obj=obj)
                    139: 
                    140:     for argname, argtype, optional, structured in parse_args(args):
                    141:         if optional:
                    142:             ret += mcgen('''
                    143: visit_start_optional(v, &has_%(c_name)s, "%(name)s", errp);
                    144: if (has_%(c_name)s) {
                    145: ''',
                    146:                          c_name=c_var(argname), name=argname)
                    147:             push_indent()
                    148:         ret += mcgen('''
                    149: visit_type_%(argtype)s(v, &%(c_name)s, "%(name)s", errp);
                    150: ''',
                    151:                       c_name=c_var(argname), name=argname, argtype=argtype)
                    152:         if optional:
                    153:             pop_indent()
                    154:             ret += mcgen('''
                    155: }
                    156: visit_end_optional(v, errp);
                    157: ''')
                    158: 
                    159:     if dealloc:
                    160:         ret += mcgen('''
                    161: qapi_dealloc_visitor_cleanup(md);
                    162: ''')
                    163:     else:
                    164:         ret += mcgen('''
                    165: qmp_input_visitor_cleanup(mi);
                    166: ''')
                    167:     pop_indent()
                    168:     return ret.rstrip()
                    169: 
                    170: def gen_marshal_output(name, args, ret_type):
                    171:     if not ret_type:
                    172:         return ""
                    173:     ret = mcgen('''
                    174: static void qmp_marshal_output_%(c_name)s(%(c_ret_type)s ret_in, QObject **ret_out, Error **errp)
                    175: {
                    176:     QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
                    177:     QmpOutputVisitor *mo = qmp_output_visitor_new();
                    178:     Visitor *v;
                    179: 
                    180:     v = qmp_output_get_visitor(mo);
                    181:     visit_type_%(ret_type)s(v, &ret_in, "unused", errp);
                    182:     if (!error_is_set(errp)) {
                    183:         *ret_out = qmp_output_get_qobject(mo);
                    184:     }
                    185:     qmp_output_visitor_cleanup(mo);
                    186:     v = qapi_dealloc_get_visitor(md);
                    187:     visit_type_%(ret_type)s(v, &ret_in, "unused", errp);
                    188:     qapi_dealloc_visitor_cleanup(md);
                    189: }
                    190: ''',
                    191:             c_ret_type=c_type(ret_type), c_name=c_var(name), ret_type=ret_type)
                    192: 
                    193:     return ret
                    194: 
                    195: def gen_marshal_input(name, args, ret_type):
                    196:     ret = mcgen('''
                    197: static void qmp_marshal_input_%(c_name)s(QDict *args, QObject **ret, Error **errp)
                    198: {
                    199: ''',
                    200:                 c_name=c_var(name))
                    201: 
                    202:     if ret_type:
                    203:         if c_type(ret_type).endswith("*"):
                    204:             retval = "    %s retval = NULL;" % c_type(ret_type)
                    205:         else:
                    206:             retval = "    %s retval;" % c_type(ret_type)
                    207:         ret += mcgen('''
                    208: %(retval)s
                    209: ''',
                    210:                      retval=retval)
                    211: 
                    212:     if len(args) > 0:
                    213:         ret += mcgen('''
                    214: %(visitor_input_containers_decl)s
                    215: %(visitor_input_vars_decl)s
                    216: 
                    217: %(visitor_input_block)s
                    218: 
                    219: ''',
                    220:                      visitor_input_containers_decl=gen_visitor_input_containers_decl(args),
                    221:                      visitor_input_vars_decl=gen_visitor_input_vars_decl(args),
                    222:                      visitor_input_block=gen_visitor_input_block(args, "QOBJECT(args)"))
                    223: 
                    224:     ret += mcgen('''
                    225:     if (error_is_set(errp)) {
                    226:         goto out;
                    227:     }
                    228: %(sync_call)s
                    229: ''',
                    230:                  sync_call=gen_sync_call(name, args, ret_type, indent=4))
                    231:     ret += mcgen('''
                    232: 
                    233: out:
                    234: ''')
                    235:     ret += mcgen('''
                    236: %(visitor_input_block_cleanup)s
                    237:     return;
                    238: }
                    239: ''',
                    240:                  visitor_input_block_cleanup=gen_visitor_input_block(args, None, dealloc=True))
                    241:     return ret
                    242: 
                    243: def gen_registry(commands):
                    244:     registry=""
                    245:     push_indent()
                    246:     for cmd in commands:
                    247:         registry += mcgen('''
                    248: qmp_register_command("%(name)s", qmp_marshal_input_%(c_name)s);
                    249: ''',
                    250:                      name=cmd['command'], c_name=c_var(cmd['command']))
                    251:     pop_indent()
                    252:     ret = mcgen('''
                    253: static void qmp_init_marshal(void)
                    254: {
                    255: %(registry)s
                    256: }
                    257: 
                    258: qapi_init(qmp_init_marshal);
                    259: ''',
                    260:                 registry=registry.rstrip())
                    261:     return ret
                    262: 
                    263: def gen_command_decl_prologue(header, guard, prefix=""):
                    264:     ret = mcgen('''
                    265: /* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
                    266: 
                    267: /*
                    268:  * schema-defined QAPI function prototypes
                    269:  *
                    270:  * Copyright IBM, Corp. 2011
                    271:  *
                    272:  * Authors:
                    273:  *  Anthony Liguori   <[email protected]>
                    274:  *
                    275:  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
                    276:  * See the COPYING.LIB file in the top-level directory.
                    277:  *
                    278:  */
                    279: 
                    280: #ifndef %(guard)s
                    281: #define %(guard)s
                    282: 
                    283: #include "%(prefix)sqapi-types.h"
                    284: #include "error.h"
                    285: 
                    286: ''',
                    287:                  header=basename(h_file), guard=guardname(h_file), prefix=prefix)
                    288:     return ret
                    289: 
                    290: def gen_command_def_prologue(prefix="", proxy=False):
                    291:     ret = mcgen('''
                    292: /* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
                    293: 
                    294: /*
                    295:  * schema-defined QMP->QAPI command dispatch
                    296:  *
                    297:  * Copyright IBM, Corp. 2011
                    298:  *
                    299:  * Authors:
                    300:  *  Anthony Liguori   <[email protected]>
                    301:  *
                    302:  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
                    303:  * See the COPYING.LIB file in the top-level directory.
                    304:  *
                    305:  */
                    306: 
                    307: #include "qemu-objects.h"
                    308: #include "qapi/qmp-core.h"
                    309: #include "qapi/qapi-visit-core.h"
                    310: #include "qapi/qmp-output-visitor.h"
                    311: #include "qapi/qmp-input-visitor.h"
                    312: #include "qapi/qapi-dealloc-visitor.h"
                    313: #include "%(prefix)sqapi-types.h"
                    314: #include "%(prefix)sqapi-visit.h"
                    315: 
                    316: ''',
                    317:                 prefix=prefix)
                    318:     if not proxy:
                    319:         ret += '#include "%sqmp-commands.h"' % prefix
                    320:     return ret + "\n"
                    321: 
                    322: 
                    323: try:
                    324:     opts, args = getopt.gnu_getopt(sys.argv[1:], "p:o:", ["prefix=", "output-dir=", "type="])
                    325: except getopt.GetoptError, err:
                    326:     print str(err)
                    327:     sys.exit(1)
                    328: 
                    329: output_dir = ""
                    330: prefix = ""
                    331: dispatch_type = "sync"
                    332: c_file = 'qmp-marshal.c'
                    333: h_file = 'qmp-commands.h'
                    334: 
                    335: for o, a in opts:
                    336:     if o in ("-p", "--prefix"):
                    337:         prefix = a
                    338:     elif o in ("-o", "--output-dir"):
                    339:         output_dir = a + "/"
                    340:     elif o in ("-t", "--type"):
                    341:         dispatch_type = a
                    342: 
                    343: c_file = output_dir + prefix + c_file
                    344: h_file = output_dir + prefix + h_file
                    345: 
                    346: try:
                    347:     os.makedirs(output_dir)
                    348: except os.error, e:
                    349:     if e.errno != errno.EEXIST:
                    350:         raise
                    351: 
                    352: exprs = parse_schema(sys.stdin)
                    353: commands = filter(lambda expr: expr.has_key('command'), exprs)
                    354: 
                    355: if dispatch_type == "sync":
                    356:     fdecl = open(h_file, 'w')
                    357:     fdef = open(c_file, 'w')
                    358:     ret = gen_command_decl_prologue(header=basename(h_file), guard=guardname(h_file), prefix=prefix)
                    359:     fdecl.write(ret)
                    360:     ret = gen_command_def_prologue(prefix=prefix)
                    361:     fdef.write(ret)
                    362: 
                    363:     for cmd in commands:
                    364:         arglist = []
                    365:         ret_type = None
                    366:         if cmd.has_key('data'):
                    367:             arglist = cmd['data']
                    368:         if cmd.has_key('returns'):
                    369:             ret_type = cmd['returns']
                    370:         ret = generate_command_decl(cmd['command'], arglist, ret_type) + "\n"
                    371:         fdecl.write(ret)
                    372:         if ret_type:
                    373:             ret = gen_marshal_output(cmd['command'], arglist, ret_type) + "\n"
                    374:             fdef.write(ret)
                    375:         ret = gen_marshal_input(cmd['command'], arglist, ret_type) + "\n"
                    376:         fdef.write(ret)
                    377: 
                    378:     fdecl.write("\n#endif");
                    379:     ret = gen_registry(commands)
                    380:     fdef.write(ret)
                    381: 
                    382:     fdef.flush()
                    383:     fdef.close()
                    384:     fdecl.flush()
                    385:     fdecl.close()

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.