Annotation of qemu/scripts/qapi-commands.py, revision 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.