summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2011-09-02 12:34:46 -0500
committerLuiz Capitulino <lcapitulino@redhat.com>2011-10-04 11:00:46 -0300
commit776574d6417cf623fb071987cdd2c6bc13271dc2 (patch)
treed1ceb48587b1e32f0e5448628b24bd9d80bdbb7b /scripts
parent2a82d936a2bda9cb01d05fc91845e82001b78632 (diff)
qapi: add code generation support for middle mode
To get the ball rolling merging QAPI, this patch introduces a "middle mode" to the code generator. In middle mode, the code generator generates marshalling functions that are compatible with the current QMP server. We absolutely need to replace the current QMP server in order to support proper asynchronous commands but using a middle mode provides a middle-ground that lets us start converting commands in tree. Note that all of the commands have been converted already in my glib branch. Middle mode only exists until we finish merging them from my branch into the main tree. Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/qapi-commands.py79
-rw-r--r--scripts/qapi-types.py3
-rw-r--r--scripts/qapi.py4
3 files changed, 71 insertions, 15 deletions
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index bf617401ad..27768049a8 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -167,9 +167,10 @@ qmp_input_visitor_cleanup(mi);
pop_indent()
return ret.rstrip()
-def gen_marshal_output(name, args, ret_type):
+def gen_marshal_output(name, args, ret_type, middle_mode):
if not ret_type:
return ""
+
ret = mcgen('''
static void qmp_marshal_output_%(c_name)s(%(c_ret_type)s ret_in, QObject **ret_out, Error **errp)
{
@@ -188,16 +189,34 @@ static void qmp_marshal_output_%(c_name)s(%(c_ret_type)s ret_in, QObject **ret_o
qapi_dealloc_visitor_cleanup(md);
}
''',
- c_ret_type=c_type(ret_type), c_name=c_var(name), ret_type=ret_type)
+ c_ret_type=c_type(ret_type), c_name=c_var(name),
+ ret_type=ret_type)
return ret
-def gen_marshal_input(name, args, ret_type):
+def gen_marshal_input_decl(name, args, ret_type, middle_mode):
+ if middle_mode:
+ return 'int qmp_marshal_input_%s(Monitor *mon, const QDict *qdict, QObject **ret)' % c_var(name)
+ else:
+ return 'static void qmp_marshal_input_%s(QDict *args, QObject **ret, Error **errp)' % c_var(name)
+
+
+
+def gen_marshal_input(name, args, ret_type, middle_mode):
+ hdr = gen_marshal_input_decl(name, args, ret_type, middle_mode)
+
ret = mcgen('''
-static void qmp_marshal_input_%(c_name)s(QDict *args, QObject **ret, Error **errp)
+%(header)s
{
''',
- c_name=c_var(name))
+ header=hdr)
+
+ if middle_mode:
+ ret += mcgen('''
+ Error *local_err = NULL;
+ Error **errp = &local_err;
+ QDict *args = (QDict *)qdict;
+''')
if ret_type:
if c_type(ret_type).endswith("*"):
@@ -220,6 +239,10 @@ static void qmp_marshal_input_%(c_name)s(QDict *args, QObject **ret, Error **err
visitor_input_containers_decl=gen_visitor_input_containers_decl(args),
visitor_input_vars_decl=gen_visitor_input_vars_decl(args),
visitor_input_block=gen_visitor_input_block(args, "QOBJECT(args)"))
+ else:
+ ret += mcgen('''
+ (void)args;
+''')
ret += mcgen('''
if (error_is_set(errp)) {
@@ -234,10 +257,29 @@ out:
''')
ret += mcgen('''
%(visitor_input_block_cleanup)s
+''',
+ visitor_input_block_cleanup=gen_visitor_input_block(args, None,
+ dealloc=True))
+
+ if middle_mode:
+ ret += mcgen('''
+
+ if (local_err) {
+ qerror_report_err(local_err);
+ error_free(local_err);
+ return -1;
+ }
+ return 0;
+''')
+ else:
+ ret += mcgen('''
return;
+''')
+
+ ret += mcgen('''
}
-''',
- visitor_input_block_cleanup=gen_visitor_input_block(args, None, dealloc=True))
+''')
+
return ret
def gen_registry(commands):
@@ -284,7 +326,7 @@ def gen_command_decl_prologue(header, guard, prefix=""):
#include "error.h"
''',
- header=basename(h_file), guard=guardname(h_file), prefix=prefix)
+ header=basename(header), guard=guardname(header), prefix=prefix)
return ret
def gen_command_def_prologue(prefix="", proxy=False):
@@ -317,11 +359,11 @@ def gen_command_def_prologue(prefix="", proxy=False):
prefix=prefix)
if not proxy:
ret += '#include "%sqmp-commands.h"' % prefix
- return ret + "\n"
+ return ret + "\n\n"
try:
- opts, args = getopt.gnu_getopt(sys.argv[1:], "p:o:", ["prefix=", "output-dir=", "type="])
+ opts, args = getopt.gnu_getopt(sys.argv[1:], "p:o:m", ["prefix=", "output-dir=", "type=", "middle"])
except getopt.GetoptError, err:
print str(err)
sys.exit(1)
@@ -331,6 +373,7 @@ prefix = ""
dispatch_type = "sync"
c_file = 'qmp-marshal.c'
h_file = 'qmp-commands.h'
+middle_mode = False
for o, a in opts:
if o in ("-p", "--prefix"):
@@ -339,6 +382,8 @@ for o, a in opts:
output_dir = a + "/"
elif o in ("-t", "--type"):
dispatch_type = a
+ elif o in ("-m", "--middle"):
+ middle_mode = True
c_file = output_dir + prefix + c_file
h_file = output_dir + prefix + h_file
@@ -370,14 +415,20 @@ if dispatch_type == "sync":
ret = generate_command_decl(cmd['command'], arglist, ret_type) + "\n"
fdecl.write(ret)
if ret_type:
- ret = gen_marshal_output(cmd['command'], arglist, ret_type) + "\n"
+ ret = gen_marshal_output(cmd['command'], arglist, ret_type, middle_mode) + "\n"
fdef.write(ret)
- ret = gen_marshal_input(cmd['command'], arglist, ret_type) + "\n"
+
+ if middle_mode:
+ fdecl.write('%s;\n' % gen_marshal_input_decl(cmd['command'], arglist, ret_type, middle_mode))
+
+ ret = gen_marshal_input(cmd['command'], arglist, ret_type, middle_mode) + "\n"
fdef.write(ret)
fdecl.write("\n#endif\n");
- ret = gen_registry(commands)
- fdef.write(ret)
+
+ if not middle_mode:
+ ret = gen_registry(commands)
+ fdef.write(ret)
fdef.flush()
fdef.close()
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index cece32546a..fc0f7af8f6 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -268,3 +268,6 @@ fdecl.write('''
fdecl.flush()
fdecl.close()
+
+fdef.flush()
+fdef.close()
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 56af2329bb..52999763ee 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -200,4 +200,6 @@ def basename(filename):
return filename.split("/")[-1]
def guardname(filename):
- return filename.replace("/", "_").replace("-", "_").split(".")[0].upper()
+ if filename.startswith('./'):
+ filename = filename[2:]
+ return filename.replace("/", "_").replace("-", "_").split(".")[0].upper() + '_H'