qapi: Fix qapi mangling of downstream names, and more
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJVViG7AAoJEDhwtADrkYZTqu0QAJCtZI2V3JZ3RmUfj/ISpekZ 9gery42k6mc9dnMp+YOEdfbYYkjtcb3NqSPQi1iJUtBS1GjYGgvC2dqYDs6Eemow OEMyat7pwzPL7oOgoXC2F3fd/LMkpGU+qNIcj9ofqrd0I46MXYCTuwS6f8j1geDQ QtG+P57g6VFNzoy6I2H7NV3u3kLw1uwUTGaIEuuoCPUmSSWJrCxmoN2pFmHK1Rwk 8rjuN5ZBLt2Vonqkj59qv/MA7/VmpasIVdbfsbnt36Jih7IyojDxpcNB80xTMlnh 2AmVXSTsP62f7xhG2xWJf9+aOu4MWqfKCmv2f4wxuLV78eHRqjBz9zvMZTzSIE3j ca71KBl5qXIPB0YdCXZrI6k6UnsXzkO8V51IfrclWqzGKX23JBaNltaKyFnAeFEU mkVZFX2STFqE1sv9rpYlXcwnXf0OzERtoSK0yeQOFCUVRdFuZkUBHMoCcb06cZMt kfP+gLt5d3hM9u1nv4rd2pfIq09HME+L6yyyG6x38EF1gvY7Up+ckqYSTaeioVWZ S4lv1Wus/QFll5EZ5RIQNmA9PW58CJ7v5E3M2II82WNcqoWjhvcnjFtmaorvJ8N1 PFqIbODjbG3WOUTe5jZnJemzSoXKeX1QhQ4nwhAPMQQpvWiheOWlgE1sAj3vnK+l 7PUF4BnOPk0pH6nCeWY6 =wbUI -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2015-05-15' into staging qapi: Fix qapi mangling of downstream names, and more # gpg: Signature made Fri May 15 17:41:31 2015 BST using RSA key ID EB918653 # gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" # gpg: aka "Markus Armbruster <armbru@pond.sub.org>" * remotes/armbru/tags/pull-qapi-2015-05-15: (26 commits) qapi: Inline gen_command_decl_prologue(), gen_command_def_prologue() qapi: Drop pointless flush() before close() qapi: Factor open_output(), close_output() out of generators qapi: Turn generators' mandatory option -i into an argument qapi: Fix generators to report command line errors decently qapi: Factor parse_command_line() out of the generators qapi: qapi-commands.py option --type is unused, drop it qapi: qapi-event.py option -b does nothing, drop it tests: Add missing dependencies on $(qapi-py) qapi: Support downstream events and commands qapi: Support downstream alternates qapi: Support downstream flat unions qapi: Support downstream simple unions qapi: Support downstream structs qapi: Support downstream enums qapi: Make c_type() consistently convert qapi names qapi: Tidy c_type() logic qapi: Move camel_to_upper(), c_enum_const() to closely related code qapi: Use c_enum_const() in generate_alternate_qtypes() qapi: Simplify c_enum_const() ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
385057cbec
14
Makefile
14
Makefile
@ -243,17 +243,17 @@ qapi-py = $(SRC_PATH)/scripts/qapi.py $(SRC_PATH)/scripts/ordereddict.py
|
||||
qga/qapi-generated/qga-qapi-types.c qga/qapi-generated/qga-qapi-types.h :\
|
||||
$(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
|
||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py \
|
||||
$(gen-out-type) -o qga/qapi-generated -p "qga-" -i $<, \
|
||||
$(gen-out-type) -o qga/qapi-generated -p "qga-" $<, \
|
||||
" GEN $@")
|
||||
qga/qapi-generated/qga-qapi-visit.c qga/qapi-generated/qga-qapi-visit.h :\
|
||||
$(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
|
||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py \
|
||||
$(gen-out-type) -o qga/qapi-generated -p "qga-" -i $<, \
|
||||
$(gen-out-type) -o qga/qapi-generated -p "qga-" $<, \
|
||||
" GEN $@")
|
||||
qga/qapi-generated/qga-qmp-commands.h qga/qapi-generated/qga-qmp-marshal.c :\
|
||||
$(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
|
||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \
|
||||
$(gen-out-type) -o qga/qapi-generated -p "qga-" -i $<, \
|
||||
$(gen-out-type) -o qga/qapi-generated -p "qga-" $<, \
|
||||
" GEN $@")
|
||||
|
||||
qapi-modules = $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi/common.json \
|
||||
@ -263,22 +263,22 @@ qapi-modules = $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi/common.json \
|
||||
qapi-types.c qapi-types.h :\
|
||||
$(qapi-modules) $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
|
||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py \
|
||||
$(gen-out-type) -o "." -b -i $<, \
|
||||
$(gen-out-type) -o "." -b $<, \
|
||||
" GEN $@")
|
||||
qapi-visit.c qapi-visit.h :\
|
||||
$(qapi-modules) $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
|
||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py \
|
||||
$(gen-out-type) -o "." -b -i $<, \
|
||||
$(gen-out-type) -o "." -b $<, \
|
||||
" GEN $@")
|
||||
qapi-event.c qapi-event.h :\
|
||||
$(qapi-modules) $(SRC_PATH)/scripts/qapi-event.py $(qapi-py)
|
||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-event.py \
|
||||
$(gen-out-type) -o "." -b -i $<, \
|
||||
$(gen-out-type) -o "." $<, \
|
||||
" GEN $@")
|
||||
qmp-commands.h qmp-marshal.c :\
|
||||
$(qapi-modules) $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
|
||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \
|
||||
$(gen-out-type) -o "." -m -i $<, \
|
||||
$(gen-out-type) -o "." -m $<, \
|
||||
" GEN $@")
|
||||
|
||||
QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qmp-commands.h)
|
||||
|
1
cpus.c
1
cpus.c
@ -1435,6 +1435,7 @@ CpuInfoList *qmp_query_cpus(Error **errp)
|
||||
info->value->CPU = cpu->cpu_index;
|
||||
info->value->current = (cpu == first_cpu);
|
||||
info->value->halted = cpu->halted;
|
||||
info->value->qom_path = object_get_canonical_path(OBJECT(cpu));
|
||||
info->value->thread_id = cpu->thread_id;
|
||||
#if defined(TARGET_I386)
|
||||
info->value->has_pc = true;
|
||||
|
@ -536,7 +536,7 @@ created code.
|
||||
Example:
|
||||
|
||||
$ python scripts/qapi-types.py --output-dir="qapi-generated" \
|
||||
--prefix="example-" --input-file=example-schema.json
|
||||
--prefix="example-" example-schema.json
|
||||
$ cat qapi-generated/example-qapi-types.c
|
||||
[Uninteresting stuff omitted...]
|
||||
|
||||
@ -623,7 +623,7 @@ $(prefix)qapi-visit.h: declarations for previously mentioned visitor
|
||||
Example:
|
||||
|
||||
$ python scripts/qapi-visit.py --output-dir="qapi-generated"
|
||||
--prefix="example-" --input-file=example-schema.json
|
||||
--prefix="example-" example-schema.json
|
||||
$ cat qapi-generated/example-qapi-visit.c
|
||||
[Uninteresting stuff omitted...]
|
||||
|
||||
@ -681,7 +681,7 @@ Example:
|
||||
error_propagate(errp, err);
|
||||
}
|
||||
$ python scripts/qapi-commands.py --output-dir="qapi-generated" \
|
||||
--prefix="example-" --input-file=example-schema.json
|
||||
--prefix="example-" example-schema.json
|
||||
$ cat qapi-generated/example-qapi-visit.h
|
||||
[Uninteresting stuff omitted...]
|
||||
|
||||
@ -715,7 +715,7 @@ $(prefix)qmp-commands.h: Function prototypes for the QMP commands
|
||||
Example:
|
||||
|
||||
$ python scripts/qapi-commands.py --output-dir="qapi-generated"
|
||||
--prefix="example-" --input-file=example-schema.json
|
||||
--prefix="example-" example-schema.json
|
||||
$ cat qapi-generated/example-qmp-marshal.c
|
||||
[Uninteresting stuff omitted...]
|
||||
|
||||
@ -806,7 +806,7 @@ $(prefix)qapi-event.c - Implementation of functions to send an event
|
||||
Example:
|
||||
|
||||
$ python scripts/qapi-event.py --output-dir="qapi-generated"
|
||||
--prefix="example-" --input-file=example-schema.json
|
||||
--prefix="example-" example-schema.json
|
||||
$ cat qapi-generated/example-qapi-event.c
|
||||
[Uninteresting stuff omitted...]
|
||||
|
||||
|
@ -232,7 +232,7 @@ Example:
|
||||
{ "event": "GUEST_PANICKED",
|
||||
"data": { "action": "pause" } }
|
||||
|
||||
MEM_HOT_UNPLUG_ERROR
|
||||
MEM_UNPLUG_ERROR
|
||||
--------------------
|
||||
Emitted when memory hot unplug error occurs.
|
||||
|
||||
@ -243,7 +243,7 @@ Data:
|
||||
|
||||
Example:
|
||||
|
||||
{ "event": "MEM_HOT_UNPLUG_ERROR"
|
||||
{ "event": "MEM_UNPLUG_ERROR"
|
||||
"data": { "device": "dimm1",
|
||||
"msg": "acpi: device unplug for unsupported device"
|
||||
},
|
||||
|
@ -679,6 +679,8 @@
|
||||
# @halted: true if the virtual CPU is in the halt state. Halt usually refers
|
||||
# to a processor specific low power mode.
|
||||
#
|
||||
# @qom_path: path to the CPU object in the QOM tree (since 2.4)
|
||||
#
|
||||
# @pc: #optional If the target is i386 or x86_64, this is the 64-bit instruction
|
||||
# pointer.
|
||||
# If the target is Sparc, this is the PC component of the
|
||||
@ -699,8 +701,10 @@
|
||||
# data is sent to the client, the guest may no longer be halted.
|
||||
##
|
||||
{ 'struct': 'CpuInfo',
|
||||
'data': {'CPU': 'int', 'current': 'bool', 'halted': 'bool', '*pc': 'int',
|
||||
'*nip': 'int', '*npc': 'int', '*PC': 'int', 'thread_id': 'int'} }
|
||||
'data': {'CPU': 'int', 'current': 'bool', 'halted': 'bool',
|
||||
'qom_path': 'str',
|
||||
'*pc': 'int', '*nip': 'int', '*npc': 'int', '*PC': 'int',
|
||||
'thread_id': 'int'} }
|
||||
|
||||
##
|
||||
# @query-cpus:
|
||||
|
@ -2569,6 +2569,7 @@ Return a json-array. Each CPU is represented by a json-object, which contains:
|
||||
- "CPU": CPU index (json-int)
|
||||
- "current": true if this is the current CPU, false otherwise (json-bool)
|
||||
- "halted": true if the cpu is halted, false otherwise (json-bool)
|
||||
- "qom_path": path to the CPU object in the QOM tree (json-str)
|
||||
- Current program counter. The key's name depends on the architecture:
|
||||
"pc": i386/x86_64 (json-int)
|
||||
"nip": PPC (json-int)
|
||||
@ -2585,14 +2586,16 @@ Example:
|
||||
"CPU":0,
|
||||
"current":true,
|
||||
"halted":false,
|
||||
"pc":3227107138
|
||||
"qom_path":"/machine/unattached/device[0]",
|
||||
"pc":3227107138,
|
||||
"thread_id":3134
|
||||
},
|
||||
{
|
||||
"CPU":1,
|
||||
"current":false,
|
||||
"halted":true,
|
||||
"pc":7108165
|
||||
"qom_path":"/machine/unattached/device[2]",
|
||||
"pc":7108165,
|
||||
"thread_id":3135
|
||||
}
|
||||
]
|
||||
|
@ -15,28 +15,19 @@
|
||||
from ordereddict import OrderedDict
|
||||
from qapi import *
|
||||
import re
|
||||
import sys
|
||||
import os
|
||||
import getopt
|
||||
import errno
|
||||
|
||||
def type_visitor(name):
|
||||
if type(name) == list:
|
||||
return 'visit_type_%sList' % name[0]
|
||||
else:
|
||||
return 'visit_type_%s' % name
|
||||
|
||||
def generate_command_decl(name, args, ret_type):
|
||||
arglist=""
|
||||
for argname, argtype, optional in parse_args(args):
|
||||
argtype = c_type(argtype, is_param=True)
|
||||
if optional:
|
||||
arglist += "bool has_%s, " % c_var(argname)
|
||||
arglist += "%s %s, " % (argtype, c_var(argname))
|
||||
arglist += "bool has_%s, " % c_name(argname)
|
||||
arglist += "%s %s, " % (argtype, c_name(argname))
|
||||
return mcgen('''
|
||||
%(ret_type)s qmp_%(name)s(%(args)sError **errp);
|
||||
''',
|
||||
ret_type=c_type(ret_type), name=c_fun(name), args=arglist).strip()
|
||||
ret_type=c_type(ret_type), name=c_name(name),
|
||||
args=arglist).strip()
|
||||
|
||||
def gen_err_check(errvar):
|
||||
if errvar:
|
||||
@ -55,14 +46,14 @@ def gen_sync_call(name, args, ret_type, indent=0):
|
||||
retval = "retval = "
|
||||
for argname, argtype, optional in parse_args(args):
|
||||
if optional:
|
||||
arglist += "has_%s, " % c_var(argname)
|
||||
arglist += "%s, " % (c_var(argname))
|
||||
arglist += "has_%s, " % c_name(argname)
|
||||
arglist += "%s, " % (c_name(argname))
|
||||
push_indent(indent)
|
||||
ret = mcgen('''
|
||||
%(retval)sqmp_%(name)s(%(args)s&local_err);
|
||||
|
||||
''',
|
||||
name=c_fun(name), args=arglist, retval=retval).rstrip()
|
||||
name=c_name(name), args=arglist, retval=retval).rstrip()
|
||||
if ret_type:
|
||||
ret += "\n" + gen_err_check('local_err')
|
||||
ret += "\n" + mcgen(''''
|
||||
@ -76,7 +67,7 @@ def gen_sync_call(name, args, ret_type, indent=0):
|
||||
def gen_marshal_output_call(name, ret_type):
|
||||
if not ret_type:
|
||||
return ""
|
||||
return "qmp_marshal_output_%s(retval, ret, &local_err);" % c_fun(name)
|
||||
return "qmp_marshal_output_%s(retval, ret, &local_err);" % c_name(name)
|
||||
|
||||
def gen_visitor_input_containers_decl(args, obj):
|
||||
ret = ""
|
||||
@ -101,17 +92,17 @@ def gen_visitor_input_vars_decl(args):
|
||||
ret += mcgen('''
|
||||
bool has_%(argname)s = false;
|
||||
''',
|
||||
argname=c_var(argname))
|
||||
argname=c_name(argname))
|
||||
if is_c_ptr(argtype):
|
||||
ret += mcgen('''
|
||||
%(argtype)s %(argname)s = NULL;
|
||||
''',
|
||||
argname=c_var(argname), argtype=c_type(argtype))
|
||||
argname=c_name(argname), argtype=c_type(argtype))
|
||||
else:
|
||||
ret += mcgen('''
|
||||
%(argtype)s %(argname)s = {0};
|
||||
''',
|
||||
argname=c_var(argname), argtype=c_type(argtype))
|
||||
argname=c_name(argname), argtype=c_type(argtype))
|
||||
|
||||
pop_indent()
|
||||
return ret.rstrip()
|
||||
@ -144,18 +135,18 @@ v = qmp_input_get_visitor(mi);
|
||||
ret += mcgen('''
|
||||
visit_optional(v, &has_%(c_name)s, "%(name)s", %(errp)s);
|
||||
''',
|
||||
c_name=c_var(argname), name=argname, errp=errparg)
|
||||
c_name=c_name(argname), name=argname, errp=errparg)
|
||||
ret += gen_err_check(errarg)
|
||||
ret += mcgen('''
|
||||
if (has_%(c_name)s) {
|
||||
''',
|
||||
c_name=c_var(argname))
|
||||
c_name=c_name(argname))
|
||||
push_indent()
|
||||
ret += mcgen('''
|
||||
%(visitor)s(v, &%(c_name)s, "%(name)s", %(errp)s);
|
||||
visit_type_%(visitor)s(v, &%(c_name)s, "%(name)s", %(errp)s);
|
||||
''',
|
||||
c_name=c_var(argname), name=argname, argtype=argtype,
|
||||
visitor=type_visitor(argtype), errp=errparg)
|
||||
c_name=c_name(argname), name=argname, argtype=argtype,
|
||||
visitor=type_name(argtype), errp=errparg)
|
||||
ret += gen_err_check(errarg)
|
||||
if optional:
|
||||
pop_indent()
|
||||
@ -183,7 +174,7 @@ static void qmp_marshal_output_%(c_name)s(%(c_ret_type)s ret_in, QObject **ret_o
|
||||
Visitor *v;
|
||||
|
||||
v = qmp_output_get_visitor(mo);
|
||||
%(visitor)s(v, &ret_in, "unused", &local_err);
|
||||
visit_type_%(visitor)s(v, &ret_in, "unused", &local_err);
|
||||
if (local_err) {
|
||||
goto out;
|
||||
}
|
||||
@ -194,20 +185,20 @@ out:
|
||||
qmp_output_visitor_cleanup(mo);
|
||||
md = qapi_dealloc_visitor_new();
|
||||
v = qapi_dealloc_get_visitor(md);
|
||||
%(visitor)s(v, &ret_in, "unused", NULL);
|
||||
visit_type_%(visitor)s(v, &ret_in, "unused", NULL);
|
||||
qapi_dealloc_visitor_cleanup(md);
|
||||
}
|
||||
''',
|
||||
c_ret_type=c_type(ret_type), c_name=c_fun(name),
|
||||
visitor=type_visitor(ret_type))
|
||||
c_ret_type=c_type(ret_type), c_name=c_name(name),
|
||||
visitor=type_name(ret_type))
|
||||
|
||||
return ret
|
||||
|
||||
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_fun(name)
|
||||
return 'int qmp_marshal_input_%s(Monitor *mon, const QDict *qdict, QObject **ret)' % c_name(name)
|
||||
else:
|
||||
return 'static void qmp_marshal_input_%s(QDict *args, QObject **ret, Error **errp)' % c_fun(name)
|
||||
return 'static void qmp_marshal_input_%s(QDict *args, QObject **ret, Error **errp)' % c_name(name)
|
||||
|
||||
|
||||
|
||||
@ -304,7 +295,7 @@ def gen_registry(commands):
|
||||
registry += mcgen('''
|
||||
qmp_register_command("%(name)s", qmp_marshal_input_%(c_name)s, %(opts)s);
|
||||
''',
|
||||
name=cmd['command'], c_name=c_fun(cmd['command']),
|
||||
name=cmd['command'], c_name=c_name(cmd['command']),
|
||||
opts=options)
|
||||
pop_indent()
|
||||
ret = mcgen('''
|
||||
@ -318,38 +309,20 @@ qapi_init(qmp_init_marshal);
|
||||
registry=registry.rstrip())
|
||||
return ret
|
||||
|
||||
def gen_command_decl_prologue(header, guard, prefix=""):
|
||||
ret = mcgen('''
|
||||
/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
|
||||
middle_mode = False
|
||||
|
||||
/*
|
||||
* schema-defined QAPI function prototypes
|
||||
*
|
||||
* Copyright IBM, Corp. 2011
|
||||
*
|
||||
* Authors:
|
||||
* Anthony Liguori <aliguori@us.ibm.com>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
||||
* See the COPYING.LIB file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
(input_file, output_dir, do_c, do_h, prefix, opts) = \
|
||||
parse_command_line("m", ["middle"])
|
||||
|
||||
#ifndef %(guard)s
|
||||
#define %(guard)s
|
||||
for o, a in opts:
|
||||
if o in ("-m", "--middle"):
|
||||
middle_mode = True
|
||||
|
||||
#include "%(prefix)sqapi-types.h"
|
||||
#include "qapi/qmp/qdict.h"
|
||||
#include "qapi/error.h"
|
||||
|
||||
''',
|
||||
header=basename(header), guard=guardname(header), prefix=prefix)
|
||||
return ret
|
||||
|
||||
def gen_command_def_prologue(prefix="", proxy=False):
|
||||
ret = mcgen('''
|
||||
/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
|
||||
exprs = parse_schema(input_file)
|
||||
commands = filter(lambda expr: expr.has_key('command'), exprs)
|
||||
commands = filter(lambda expr: not expr.has_key('gen'), commands)
|
||||
|
||||
c_comment = '''
|
||||
/*
|
||||
* schema-defined QMP->QAPI command dispatch
|
||||
*
|
||||
@ -362,7 +335,27 @@ def gen_command_def_prologue(prefix="", proxy=False):
|
||||
* See the COPYING.LIB file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
'''
|
||||
h_comment = '''
|
||||
/*
|
||||
* schema-defined QAPI function prototypes
|
||||
*
|
||||
* Copyright IBM, Corp. 2011
|
||||
*
|
||||
* Authors:
|
||||
* Anthony Liguori <aliguori@us.ibm.com>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
||||
* See the COPYING.LIB file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
'''
|
||||
|
||||
(fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
|
||||
'qmp-marshal.c', 'qmp-commands.h',
|
||||
c_comment, h_comment)
|
||||
|
||||
fdef.write(mcgen('''
|
||||
#include "qemu-common.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qapi/qmp/qerror.h"
|
||||
@ -374,82 +367,20 @@ def gen_command_def_prologue(prefix="", proxy=False):
|
||||
#include "qapi/dealloc-visitor.h"
|
||||
#include "%(prefix)sqapi-types.h"
|
||||
#include "%(prefix)sqapi-visit.h"
|
||||
#include "%(prefix)sqmp-commands.h"
|
||||
|
||||
''',
|
||||
prefix=prefix)
|
||||
if not proxy:
|
||||
ret += '#include "%sqmp-commands.h"' % prefix
|
||||
return ret + "\n\n"
|
||||
prefix=prefix))
|
||||
|
||||
fdecl.write(mcgen('''
|
||||
#include "%(prefix)sqapi-types.h"
|
||||
#include "qapi/qmp/qdict.h"
|
||||
#include "qapi/error.h"
|
||||
|
||||
try:
|
||||
opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:i:o:m",
|
||||
["source", "header", "prefix=",
|
||||
"input-file=", "output-dir=",
|
||||
"type=", "middle"])
|
||||
except getopt.GetoptError, err:
|
||||
print str(err)
|
||||
sys.exit(1)
|
||||
''',
|
||||
prefix=prefix))
|
||||
|
||||
output_dir = ""
|
||||
prefix = ""
|
||||
dispatch_type = "sync"
|
||||
c_file = 'qmp-marshal.c'
|
||||
h_file = 'qmp-commands.h'
|
||||
middle_mode = False
|
||||
|
||||
do_c = False
|
||||
do_h = False
|
||||
|
||||
for o, a in opts:
|
||||
if o in ("-p", "--prefix"):
|
||||
prefix = a
|
||||
elif o in ("-i", "--input-file"):
|
||||
input_file = a
|
||||
elif o in ("-o", "--output-dir"):
|
||||
output_dir = a + "/"
|
||||
elif o in ("-t", "--type"):
|
||||
dispatch_type = a
|
||||
elif o in ("-m", "--middle"):
|
||||
middle_mode = True
|
||||
elif o in ("-c", "--source"):
|
||||
do_c = True
|
||||
elif o in ("-h", "--header"):
|
||||
do_h = True
|
||||
|
||||
if not do_c and not do_h:
|
||||
do_c = True
|
||||
do_h = True
|
||||
|
||||
c_file = output_dir + prefix + c_file
|
||||
h_file = output_dir + prefix + h_file
|
||||
|
||||
def maybe_open(really, name, opt):
|
||||
if really:
|
||||
return open(name, opt)
|
||||
else:
|
||||
import StringIO
|
||||
return StringIO.StringIO()
|
||||
|
||||
try:
|
||||
os.makedirs(output_dir)
|
||||
except os.error, e:
|
||||
if e.errno != errno.EEXIST:
|
||||
raise
|
||||
|
||||
exprs = parse_schema(input_file)
|
||||
commands = filter(lambda expr: expr.has_key('command'), exprs)
|
||||
commands = filter(lambda expr: not expr.has_key('gen'), commands)
|
||||
|
||||
if dispatch_type == "sync":
|
||||
fdecl = maybe_open(do_h, h_file, 'w')
|
||||
fdef = maybe_open(do_c, c_file, 'w')
|
||||
ret = gen_command_decl_prologue(header=basename(h_file), guard=guardname(h_file), prefix=prefix)
|
||||
fdecl.write(ret)
|
||||
ret = gen_command_def_prologue(prefix=prefix)
|
||||
fdef.write(ret)
|
||||
|
||||
for cmd in commands:
|
||||
for cmd in commands:
|
||||
arglist = []
|
||||
ret_type = None
|
||||
if cmd.has_key('data'):
|
||||
@ -468,13 +399,8 @@ if dispatch_type == "sync":
|
||||
ret = gen_marshal_input(cmd['command'], arglist, ret_type, middle_mode) + "\n"
|
||||
fdef.write(ret)
|
||||
|
||||
fdecl.write("\n#endif\n");
|
||||
|
||||
if not middle_mode:
|
||||
if not middle_mode:
|
||||
ret = gen_registry(commands)
|
||||
fdef.write(ret)
|
||||
|
||||
fdef.flush()
|
||||
fdef.close()
|
||||
fdecl.flush()
|
||||
fdecl.close()
|
||||
close_output(fdef, fdecl)
|
||||
|
@ -11,23 +11,19 @@
|
||||
|
||||
from ordereddict import OrderedDict
|
||||
from qapi import *
|
||||
import sys
|
||||
import os
|
||||
import getopt
|
||||
import errno
|
||||
|
||||
def _generate_event_api_name(event_name, params):
|
||||
api_name = "void qapi_event_send_%s(" % c_fun(event_name).lower();
|
||||
api_name = "void qapi_event_send_%s(" % c_name(event_name).lower();
|
||||
l = len(api_name)
|
||||
|
||||
if params:
|
||||
for argname, argentry, optional in parse_args(params):
|
||||
if optional:
|
||||
api_name += "bool has_%s,\n" % c_var(argname)
|
||||
api_name += "bool has_%s,\n" % c_name(argname)
|
||||
api_name += "".ljust(l)
|
||||
|
||||
api_name += "%s %s,\n" % (c_type(argentry, is_param=True),
|
||||
c_var(argname))
|
||||
c_name(argname))
|
||||
api_name += "".ljust(l)
|
||||
|
||||
api_name += "Error **errp)"
|
||||
@ -98,7 +94,7 @@ def generate_event_implement(api_name, event_name, params):
|
||||
ret += mcgen("""
|
||||
if (has_%(var)s) {
|
||||
""",
|
||||
var = c_var(argname))
|
||||
var = c_name(argname))
|
||||
push_indent()
|
||||
|
||||
if argentry == "str":
|
||||
@ -113,7 +109,7 @@ def generate_event_implement(api_name, event_name, params):
|
||||
}
|
||||
""",
|
||||
var_type = var_type,
|
||||
var = c_var(argname),
|
||||
var = c_name(argname),
|
||||
type = type_name(argentry),
|
||||
name = argname)
|
||||
|
||||
@ -177,7 +173,7 @@ typedef enum %(event_enum_name)s
|
||||
event_enum_name = event_enum_name)
|
||||
|
||||
# append automatically generated _MAX value
|
||||
enum_max_value = generate_enum_full_value(event_enum_name, "MAX")
|
||||
enum_max_value = c_enum_const(event_enum_name, "MAX")
|
||||
enum_values = event_enum_values + [ enum_max_value ]
|
||||
|
||||
i = 0
|
||||
@ -216,67 +212,9 @@ const char *%(event_enum_name)s_lookup[] = {
|
||||
''')
|
||||
return ret
|
||||
|
||||
(input_file, output_dir, do_c, do_h, prefix, dummy) = parse_command_line()
|
||||
|
||||
# Start the real job
|
||||
|
||||
try:
|
||||
opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:i:o:",
|
||||
["source", "header", "builtins", "prefix=",
|
||||
"input-file=", "output-dir="])
|
||||
except getopt.GetoptError, err:
|
||||
print str(err)
|
||||
sys.exit(1)
|
||||
|
||||
input_file = ""
|
||||
output_dir = ""
|
||||
prefix = ""
|
||||
c_file = 'qapi-event.c'
|
||||
h_file = 'qapi-event.h'
|
||||
|
||||
do_c = False
|
||||
do_h = False
|
||||
do_builtins = False
|
||||
|
||||
for o, a in opts:
|
||||
if o in ("-p", "--prefix"):
|
||||
prefix = a
|
||||
elif o in ("-i", "--input-file"):
|
||||
input_file = a
|
||||
elif o in ("-o", "--output-dir"):
|
||||
output_dir = a + "/"
|
||||
elif o in ("-c", "--source"):
|
||||
do_c = True
|
||||
elif o in ("-h", "--header"):
|
||||
do_h = True
|
||||
elif o in ("-b", "--builtins"):
|
||||
do_builtins = True
|
||||
|
||||
if not do_c and not do_h:
|
||||
do_c = True
|
||||
do_h = True
|
||||
|
||||
c_file = output_dir + prefix + c_file
|
||||
h_file = output_dir + prefix + h_file
|
||||
|
||||
try:
|
||||
os.makedirs(output_dir)
|
||||
except os.error, e:
|
||||
if e.errno != errno.EEXIST:
|
||||
raise
|
||||
|
||||
def maybe_open(really, name, opt):
|
||||
if really:
|
||||
return open(name, opt)
|
||||
else:
|
||||
import StringIO
|
||||
return StringIO.StringIO()
|
||||
|
||||
fdef = maybe_open(do_c, c_file, 'w')
|
||||
fdecl = maybe_open(do_h, h_file, 'w')
|
||||
|
||||
fdef.write(mcgen('''
|
||||
/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
|
||||
|
||||
c_comment = '''
|
||||
/*
|
||||
* schema-defined QAPI event functions
|
||||
*
|
||||
@ -289,41 +227,43 @@ fdef.write(mcgen('''
|
||||
* See the COPYING.LIB file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
'''
|
||||
h_comment = '''
|
||||
/*
|
||||
* schema-defined QAPI event functions
|
||||
*
|
||||
* Copyright (c) 2014 Wenchao Xia
|
||||
*
|
||||
* Authors:
|
||||
* Wenchao Xia <wenchaoqemu@gmail.com>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
||||
* See the COPYING.LIB file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
'''
|
||||
|
||||
(fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
|
||||
'qapi-event.c', 'qapi-event.h',
|
||||
c_comment, h_comment)
|
||||
|
||||
fdef.write(mcgen('''
|
||||
#include "qemu-common.h"
|
||||
#include "%(header)s"
|
||||
#include "%(prefix)sqapi-event.h"
|
||||
#include "%(prefix)sqapi-visit.h"
|
||||
#include "qapi/qmp-output-visitor.h"
|
||||
#include "qapi/qmp-event.h"
|
||||
|
||||
''',
|
||||
prefix=prefix, header=basename(h_file)))
|
||||
prefix=prefix))
|
||||
|
||||
fdecl.write(mcgen('''
|
||||
/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
|
||||
|
||||
/*
|
||||
* schema-defined QAPI event functions
|
||||
*
|
||||
* Copyright (c) 2014 Wenchao Xia
|
||||
*
|
||||
* Authors:
|
||||
* Wenchao Xia <wenchaoqemu@gmail.com>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
||||
* See the COPYING.LIB file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef %(guard)s
|
||||
#define %(guard)s
|
||||
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/qmp/qdict.h"
|
||||
#include "%(prefix)sqapi-types.h"
|
||||
|
||||
''',
|
||||
prefix=prefix, guard=guardname(h_file)))
|
||||
prefix=prefix))
|
||||
|
||||
exprs = parse_schema(input_file)
|
||||
|
||||
@ -343,8 +283,7 @@ for expr in exprs:
|
||||
fdecl.write(ret)
|
||||
|
||||
# We need an enum value per event
|
||||
event_enum_value = generate_enum_full_value(event_enum_name,
|
||||
event_name)
|
||||
event_enum_value = c_enum_const(event_enum_name, event_name)
|
||||
ret = generate_event_implement(api_name, event_name, params)
|
||||
fdef.write(ret)
|
||||
|
||||
@ -357,12 +296,4 @@ fdecl.write(ret)
|
||||
ret = generate_event_enum_lookup(event_enum_name, event_enum_strings)
|
||||
fdef.write(ret)
|
||||
|
||||
fdecl.write('''
|
||||
#endif
|
||||
''')
|
||||
|
||||
fdecl.flush()
|
||||
fdecl.close()
|
||||
|
||||
fdef.flush()
|
||||
fdef.close()
|
||||
close_output(fdef, fdecl)
|
||||
|
@ -11,10 +11,6 @@
|
||||
|
||||
from ordereddict import OrderedDict
|
||||
from qapi import *
|
||||
import sys
|
||||
import os
|
||||
import getopt
|
||||
import errno
|
||||
|
||||
def generate_fwd_struct(name, members, builtin_type=False):
|
||||
if builtin_type:
|
||||
@ -45,7 +41,7 @@ typedef struct %(name)sList
|
||||
struct %(name)sList *next;
|
||||
} %(name)sList;
|
||||
''',
|
||||
name=name)
|
||||
name=c_name(name))
|
||||
|
||||
def generate_fwd_enum_struct(name, members):
|
||||
return mcgen('''
|
||||
@ -58,7 +54,7 @@ typedef struct %(name)sList
|
||||
struct %(name)sList *next;
|
||||
} %(name)sList;
|
||||
''',
|
||||
name=name)
|
||||
name=c_name(name))
|
||||
|
||||
def generate_struct_fields(members):
|
||||
ret = ''
|
||||
@ -68,11 +64,11 @@ def generate_struct_fields(members):
|
||||
ret += mcgen('''
|
||||
bool has_%(c_name)s;
|
||||
''',
|
||||
c_name=c_var(argname))
|
||||
c_name=c_name(argname))
|
||||
ret += mcgen('''
|
||||
%(c_type)s %(c_name)s;
|
||||
''',
|
||||
c_type=c_type(argentry), c_name=c_var(argname))
|
||||
c_type=c_type(argentry), c_name=c_name(argname))
|
||||
|
||||
return ret
|
||||
|
||||
@ -87,7 +83,7 @@ def generate_struct(expr):
|
||||
struct %(name)s
|
||||
{
|
||||
''',
|
||||
name=structname)
|
||||
name=c_name(structname))
|
||||
|
||||
if base:
|
||||
ret += generate_struct_fields({'base': base})
|
||||
@ -115,16 +111,16 @@ def generate_enum_lookup(name, values):
|
||||
ret = mcgen('''
|
||||
const char *%(name)s_lookup[] = {
|
||||
''',
|
||||
name=name)
|
||||
name=c_name(name))
|
||||
i = 0
|
||||
for value in values:
|
||||
index = generate_enum_full_value(name, value)
|
||||
index = c_enum_const(name, value)
|
||||
ret += mcgen('''
|
||||
[%(index)s] = "%(value)s",
|
||||
''',
|
||||
index = index, value = value)
|
||||
|
||||
max_index = generate_enum_full_value(name, 'MAX')
|
||||
max_index = c_enum_const(name, 'MAX')
|
||||
ret += mcgen('''
|
||||
[%(max_index)s] = NULL,
|
||||
};
|
||||
@ -134,6 +130,7 @@ const char *%(name)s_lookup[] = {
|
||||
return ret
|
||||
|
||||
def generate_enum(name, values):
|
||||
name = c_name(name)
|
||||
lookup_decl = mcgen('''
|
||||
extern const char *%(name)s_lookup[];
|
||||
''',
|
||||
@ -150,7 +147,7 @@ typedef enum %(name)s
|
||||
|
||||
i = 0
|
||||
for value in enum_values:
|
||||
enum_full_value = generate_enum_full_value(name, value)
|
||||
enum_full_value = c_enum_const(name, value)
|
||||
enum_decl += mcgen('''
|
||||
%(enum_full_value)s = %(i)d,
|
||||
''',
|
||||
@ -173,18 +170,17 @@ def generate_alternate_qtypes(expr):
|
||||
ret = mcgen('''
|
||||
const int %(name)s_qtypes[QTYPE_MAX] = {
|
||||
''',
|
||||
name=name)
|
||||
name=c_name(name))
|
||||
|
||||
for key in members:
|
||||
qtype = find_alternate_member_qtype(members[key])
|
||||
assert qtype, "Invalid alternate member"
|
||||
|
||||
ret += mcgen('''
|
||||
[ %(qtype)s ] = %(abbrev)s_KIND_%(enum)s,
|
||||
[%(qtype)s] = %(enum_const)s,
|
||||
''',
|
||||
qtype = qtype,
|
||||
abbrev = de_camel_case(name).upper(),
|
||||
enum = c_fun(de_camel_case(key),False).upper())
|
||||
enum_const = c_enum_const(name + 'Kind', key))
|
||||
|
||||
ret += mcgen('''
|
||||
};
|
||||
@ -194,7 +190,7 @@ const int %(name)s_qtypes[QTYPE_MAX] = {
|
||||
|
||||
def generate_union(expr, meta):
|
||||
|
||||
name = expr[meta]
|
||||
name = c_name(expr[meta])
|
||||
typeinfo = expr['data']
|
||||
|
||||
base = expr.get('base')
|
||||
@ -214,14 +210,14 @@ struct %(name)s
|
||||
void *data;
|
||||
''',
|
||||
name=name,
|
||||
discriminator_type_name=discriminator_type_name)
|
||||
discriminator_type_name=c_name(discriminator_type_name))
|
||||
|
||||
for key in typeinfo:
|
||||
ret += mcgen('''
|
||||
%(c_type)s %(c_name)s;
|
||||
''',
|
||||
c_type=c_type(typeinfo[key]),
|
||||
c_name=c_fun(key))
|
||||
c_name=c_name(key))
|
||||
|
||||
ret += mcgen('''
|
||||
};
|
||||
@ -249,15 +245,15 @@ extern const int %(name)s_qtypes[];
|
||||
|
||||
def generate_type_cleanup_decl(name):
|
||||
ret = mcgen('''
|
||||
void qapi_free_%(type)s(%(c_type)s obj);
|
||||
void qapi_free_%(name)s(%(c_type)s obj);
|
||||
''',
|
||||
c_type=c_type(name),type=name)
|
||||
c_type=c_type(name), name=c_name(name))
|
||||
return ret
|
||||
|
||||
def generate_type_cleanup(name):
|
||||
ret = mcgen('''
|
||||
|
||||
void qapi_free_%(type)s(%(c_type)s obj)
|
||||
void qapi_free_%(name)s(%(c_type)s obj)
|
||||
{
|
||||
QapiDeallocVisitor *md;
|
||||
Visitor *v;
|
||||
@ -268,72 +264,23 @@ void qapi_free_%(type)s(%(c_type)s obj)
|
||||
|
||||
md = qapi_dealloc_visitor_new();
|
||||
v = qapi_dealloc_get_visitor(md);
|
||||
visit_type_%(type)s(v, &obj, NULL, NULL);
|
||||
visit_type_%(name)s(v, &obj, NULL, NULL);
|
||||
qapi_dealloc_visitor_cleanup(md);
|
||||
}
|
||||
''',
|
||||
c_type=c_type(name),type=name)
|
||||
c_type=c_type(name), name=c_name(name))
|
||||
return ret
|
||||
|
||||
|
||||
try:
|
||||
opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:i:o:",
|
||||
["source", "header", "builtins",
|
||||
"prefix=", "input-file=", "output-dir="])
|
||||
except getopt.GetoptError, err:
|
||||
print str(err)
|
||||
sys.exit(1)
|
||||
|
||||
output_dir = ""
|
||||
input_file = ""
|
||||
prefix = ""
|
||||
c_file = 'qapi-types.c'
|
||||
h_file = 'qapi-types.h'
|
||||
|
||||
do_c = False
|
||||
do_h = False
|
||||
do_builtins = False
|
||||
|
||||
(input_file, output_dir, do_c, do_h, prefix, opts) = \
|
||||
parse_command_line("b", ["builtins"])
|
||||
|
||||
for o, a in opts:
|
||||
if o in ("-p", "--prefix"):
|
||||
prefix = a
|
||||
elif o in ("-i", "--input-file"):
|
||||
input_file = a
|
||||
elif o in ("-o", "--output-dir"):
|
||||
output_dir = a + "/"
|
||||
elif o in ("-c", "--source"):
|
||||
do_c = True
|
||||
elif o in ("-h", "--header"):
|
||||
do_h = True
|
||||
elif o in ("-b", "--builtins"):
|
||||
if o in ("-b", "--builtins"):
|
||||
do_builtins = True
|
||||
|
||||
if not do_c and not do_h:
|
||||
do_c = True
|
||||
do_h = True
|
||||
|
||||
c_file = output_dir + prefix + c_file
|
||||
h_file = output_dir + prefix + h_file
|
||||
|
||||
try:
|
||||
os.makedirs(output_dir)
|
||||
except os.error, e:
|
||||
if e.errno != errno.EEXIST:
|
||||
raise
|
||||
|
||||
def maybe_open(really, name, opt):
|
||||
if really:
|
||||
return open(name, opt)
|
||||
else:
|
||||
import StringIO
|
||||
return StringIO.StringIO()
|
||||
|
||||
fdef = maybe_open(do_c, c_file, 'w')
|
||||
fdecl = maybe_open(do_h, h_file, 'w')
|
||||
|
||||
fdef.write(mcgen('''
|
||||
/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
|
||||
|
||||
c_comment = '''
|
||||
/*
|
||||
* deallocation functions for schema-defined QAPI types
|
||||
*
|
||||
@ -347,16 +294,8 @@ fdef.write(mcgen('''
|
||||
* See the COPYING.LIB file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "qapi/dealloc-visitor.h"
|
||||
#include "%(prefix)sqapi-types.h"
|
||||
#include "%(prefix)sqapi-visit.h"
|
||||
|
||||
''', prefix=prefix))
|
||||
|
||||
fdecl.write(mcgen('''
|
||||
/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
|
||||
|
||||
'''
|
||||
h_comment = '''
|
||||
/*
|
||||
* schema-defined QAPI types
|
||||
*
|
||||
@ -369,15 +308,25 @@ fdecl.write(mcgen('''
|
||||
* See the COPYING.LIB file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
'''
|
||||
|
||||
#ifndef %(guard)s
|
||||
#define %(guard)s
|
||||
(fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
|
||||
'qapi-types.c', 'qapi-types.h',
|
||||
c_comment, h_comment)
|
||||
|
||||
fdef.write(mcgen('''
|
||||
#include "qapi/dealloc-visitor.h"
|
||||
#include "%(prefix)sqapi-types.h"
|
||||
#include "%(prefix)sqapi-visit.h"
|
||||
|
||||
''',
|
||||
prefix=prefix))
|
||||
|
||||
fdecl.write(mcgen('''
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
''',
|
||||
guard=guardname(h_file)))
|
||||
'''))
|
||||
|
||||
exprs = parse_schema(input_file)
|
||||
exprs = filter(lambda expr: not expr.has_key('gen'), exprs)
|
||||
@ -455,12 +404,4 @@ for expr in exprs:
|
||||
continue
|
||||
fdecl.write(ret)
|
||||
|
||||
fdecl.write('''
|
||||
#endif
|
||||
''')
|
||||
|
||||
fdecl.flush()
|
||||
fdecl.close()
|
||||
|
||||
fdef.flush()
|
||||
fdef.close()
|
||||
close_output(fdef, fdecl)
|
||||
|
@ -15,10 +15,6 @@
|
||||
from ordereddict import OrderedDict
|
||||
from qapi import *
|
||||
import re
|
||||
import sys
|
||||
import os
|
||||
import getopt
|
||||
import errno
|
||||
|
||||
implicit_structs = []
|
||||
|
||||
@ -56,7 +52,7 @@ static void visit_type_%(name)s_fields(Visitor *m, %(name)s **obj, Error **errp)
|
||||
{
|
||||
Error *err = NULL;
|
||||
''',
|
||||
name=name)
|
||||
name=c_name(name))
|
||||
push_indent()
|
||||
|
||||
if base:
|
||||
@ -66,7 +62,7 @@ if (err) {
|
||||
goto out;
|
||||
}
|
||||
''',
|
||||
type=type_name(base), c_name=c_var('base'))
|
||||
type=type_name(base), c_name=c_name('base'))
|
||||
|
||||
for argname, argentry, optional in parse_args(members):
|
||||
if optional:
|
||||
@ -74,13 +70,13 @@ if (err) {
|
||||
visit_optional(m, &(*obj)->has_%(c_name)s, "%(name)s", &err);
|
||||
if (!err && (*obj)->has_%(c_name)s) {
|
||||
''',
|
||||
c_name=c_var(argname), name=argname)
|
||||
c_name=c_name(argname), name=argname)
|
||||
push_indent()
|
||||
|
||||
ret += mcgen('''
|
||||
visit_type_%(type)s(m, &(*obj)->%(c_name)s, "%(name)s", &err);
|
||||
''',
|
||||
type=type_name(argentry), c_name=c_var(argname),
|
||||
type=type_name(argentry), c_name=c_name(argname),
|
||||
name=argname)
|
||||
|
||||
if optional:
|
||||
@ -111,16 +107,16 @@ def generate_visit_struct_body(name, members):
|
||||
ret = mcgen('''
|
||||
Error *err = NULL;
|
||||
|
||||
visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s), &err);
|
||||
visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(c_name)s), &err);
|
||||
if (!err) {
|
||||
if (*obj) {
|
||||
visit_type_%(name)s_fields(m, obj, errp);
|
||||
visit_type_%(c_name)s_fields(m, obj, errp);
|
||||
}
|
||||
visit_end_struct(m, &err);
|
||||
}
|
||||
error_propagate(errp, err);
|
||||
''',
|
||||
name=name)
|
||||
name=name, c_name=c_name(name))
|
||||
|
||||
return ret
|
||||
|
||||
@ -137,7 +133,7 @@ def generate_visit_struct(expr):
|
||||
void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **errp)
|
||||
{
|
||||
''',
|
||||
name=name)
|
||||
name=c_name(name))
|
||||
|
||||
ret += generate_visit_struct_body(name, members)
|
||||
|
||||
@ -173,7 +169,7 @@ out:
|
||||
error_propagate(errp, err);
|
||||
}
|
||||
''',
|
||||
name=name)
|
||||
name=type_name(name))
|
||||
|
||||
def generate_visit_enum(name, members):
|
||||
return mcgen('''
|
||||
@ -183,7 +179,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s *obj, const char *name, Error **er
|
||||
visit_type_enum(m, (int *)obj, %(name)s_lookup, "%(name)s", name, errp);
|
||||
}
|
||||
''',
|
||||
name=name)
|
||||
name=c_name(name))
|
||||
|
||||
def generate_visit_alternate(name, members):
|
||||
ret = mcgen('''
|
||||
@ -202,11 +198,11 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **e
|
||||
}
|
||||
switch ((*obj)->kind) {
|
||||
''',
|
||||
name=name)
|
||||
name=c_name(name))
|
||||
|
||||
# For alternate, always use the default enum type automatically generated
|
||||
# as "'%sKind' % (name)"
|
||||
disc_type = '%sKind' % (name)
|
||||
# as name + 'Kind'
|
||||
disc_type = c_name(name) + 'Kind'
|
||||
|
||||
for key in members:
|
||||
assert (members[key] in builtin_types.keys()
|
||||
@ -214,7 +210,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **e
|
||||
or find_union(members[key])
|
||||
or find_enum(members[key])), "Invalid alternate member"
|
||||
|
||||
enum_full_value = generate_enum_full_value(disc_type, key)
|
||||
enum_full_value = c_enum_const(disc_type, key)
|
||||
ret += mcgen('''
|
||||
case %(enum_full_value)s:
|
||||
visit_type_%(c_type)s(m, &(*obj)->%(c_name)s, name, &err);
|
||||
@ -222,7 +218,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **e
|
||||
''',
|
||||
enum_full_value = enum_full_value,
|
||||
c_type = type_name(members[key]),
|
||||
c_name = c_fun(key))
|
||||
c_name = c_name(key))
|
||||
|
||||
ret += mcgen('''
|
||||
default:
|
||||
@ -252,12 +248,12 @@ def generate_visit_union(expr):
|
||||
if enum_define:
|
||||
# Use the enum type as discriminator
|
||||
ret = ""
|
||||
disc_type = enum_define['enum_name']
|
||||
disc_type = c_name(enum_define['enum_name'])
|
||||
else:
|
||||
# There will always be a discriminator in the C switch code, by default
|
||||
# it is an enum type generated silently as "'%sKind' % (name)"
|
||||
ret = generate_visit_enum('%sKind' % name, members.keys())
|
||||
disc_type = '%sKind' % (name)
|
||||
# it is an enum type generated silently
|
||||
ret = generate_visit_enum(name + 'Kind', members.keys())
|
||||
disc_type = c_name(name) + 'Kind'
|
||||
|
||||
if base:
|
||||
assert discriminator
|
||||
@ -281,7 +277,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **e
|
||||
}
|
||||
if (*obj) {
|
||||
''',
|
||||
name=name)
|
||||
name=c_name(name))
|
||||
|
||||
if base:
|
||||
ret += mcgen('''
|
||||
@ -290,7 +286,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **e
|
||||
goto out_obj;
|
||||
}
|
||||
''',
|
||||
name=name)
|
||||
name=c_name(name))
|
||||
|
||||
if not discriminator:
|
||||
disc_key = "type"
|
||||
@ -315,7 +311,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **e
|
||||
else:
|
||||
fmt = 'visit_type_implicit_%(c_type)s(m, &(*obj)->%(c_name)s, &err);'
|
||||
|
||||
enum_full_value = generate_enum_full_value(disc_type, key)
|
||||
enum_full_value = c_enum_const(disc_type, key)
|
||||
ret += mcgen('''
|
||||
case %(enum_full_value)s:
|
||||
''' + fmt + '''
|
||||
@ -323,7 +319,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **e
|
||||
''',
|
||||
enum_full_value = enum_full_value,
|
||||
c_type=type_name(members[key]),
|
||||
c_name=c_fun(key))
|
||||
c_name=c_name(key))
|
||||
|
||||
ret += mcgen('''
|
||||
default:
|
||||
@ -347,6 +343,7 @@ out:
|
||||
def generate_declaration(name, members, builtin_type=False):
|
||||
ret = ""
|
||||
if not builtin_type:
|
||||
name = c_name(name)
|
||||
ret += mcgen('''
|
||||
|
||||
void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **errp);
|
||||
@ -364,7 +361,7 @@ def generate_enum_declaration(name, members):
|
||||
ret = mcgen('''
|
||||
void visit_type_%(name)sList(Visitor *m, %(name)sList **obj, const char *name, Error **errp);
|
||||
''',
|
||||
name=name)
|
||||
name=c_name(name))
|
||||
|
||||
return ret
|
||||
|
||||
@ -373,108 +370,62 @@ def generate_decl_enum(name, members):
|
||||
|
||||
void visit_type_%(name)s(Visitor *m, %(name)s *obj, const char *name, Error **errp);
|
||||
''',
|
||||
name=name)
|
||||
name=c_name(name))
|
||||
|
||||
try:
|
||||
opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:i:o:",
|
||||
["source", "header", "builtins", "prefix=",
|
||||
"input-file=", "output-dir="])
|
||||
except getopt.GetoptError, err:
|
||||
print str(err)
|
||||
sys.exit(1)
|
||||
|
||||
input_file = ""
|
||||
output_dir = ""
|
||||
prefix = ""
|
||||
c_file = 'qapi-visit.c'
|
||||
h_file = 'qapi-visit.h'
|
||||
|
||||
do_c = False
|
||||
do_h = False
|
||||
do_builtins = False
|
||||
|
||||
(input_file, output_dir, do_c, do_h, prefix, opts) = \
|
||||
parse_command_line("b", ["builtins"])
|
||||
|
||||
for o, a in opts:
|
||||
if o in ("-p", "--prefix"):
|
||||
prefix = a
|
||||
elif o in ("-i", "--input-file"):
|
||||
input_file = a
|
||||
elif o in ("-o", "--output-dir"):
|
||||
output_dir = a + "/"
|
||||
elif o in ("-c", "--source"):
|
||||
do_c = True
|
||||
elif o in ("-h", "--header"):
|
||||
do_h = True
|
||||
elif o in ("-b", "--builtins"):
|
||||
if o in ("-b", "--builtins"):
|
||||
do_builtins = True
|
||||
|
||||
if not do_c and not do_h:
|
||||
do_c = True
|
||||
do_h = True
|
||||
c_comment = '''
|
||||
/*
|
||||
* schema-defined QAPI visitor functions
|
||||
*
|
||||
* Copyright IBM, Corp. 2011
|
||||
*
|
||||
* Authors:
|
||||
* Anthony Liguori <aliguori@us.ibm.com>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
||||
* See the COPYING.LIB file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
'''
|
||||
h_comment = '''
|
||||
/*
|
||||
* schema-defined QAPI visitor functions
|
||||
*
|
||||
* Copyright IBM, Corp. 2011
|
||||
*
|
||||
* Authors:
|
||||
* Anthony Liguori <aliguori@us.ibm.com>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
||||
* See the COPYING.LIB file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
'''
|
||||
|
||||
c_file = output_dir + prefix + c_file
|
||||
h_file = output_dir + prefix + h_file
|
||||
|
||||
try:
|
||||
os.makedirs(output_dir)
|
||||
except os.error, e:
|
||||
if e.errno != errno.EEXIST:
|
||||
raise
|
||||
|
||||
def maybe_open(really, name, opt):
|
||||
if really:
|
||||
return open(name, opt)
|
||||
else:
|
||||
import StringIO
|
||||
return StringIO.StringIO()
|
||||
|
||||
fdef = maybe_open(do_c, c_file, 'w')
|
||||
fdecl = maybe_open(do_h, h_file, 'w')
|
||||
(fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
|
||||
'qapi-visit.c', 'qapi-visit.h',
|
||||
c_comment, h_comment)
|
||||
|
||||
fdef.write(mcgen('''
|
||||
/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
|
||||
|
||||
/*
|
||||
* schema-defined QAPI visitor functions
|
||||
*
|
||||
* Copyright IBM, Corp. 2011
|
||||
*
|
||||
* Authors:
|
||||
* Anthony Liguori <aliguori@us.ibm.com>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
||||
* See the COPYING.LIB file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "%(header)s"
|
||||
#include "%(prefix)sqapi-visit.h"
|
||||
''',
|
||||
header=basename(h_file)))
|
||||
prefix = prefix))
|
||||
|
||||
fdecl.write(mcgen('''
|
||||
/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
|
||||
|
||||
/*
|
||||
* schema-defined QAPI visitor functions
|
||||
*
|
||||
* Copyright IBM, Corp. 2011
|
||||
*
|
||||
* Authors:
|
||||
* Anthony Liguori <aliguori@us.ibm.com>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
||||
* See the COPYING.LIB file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef %(guard)s
|
||||
#define %(guard)s
|
||||
|
||||
#include "qapi/visitor.h"
|
||||
#include "%(prefix)sqapi-types.h"
|
||||
|
||||
''',
|
||||
prefix=prefix, guard=guardname(h_file)))
|
||||
prefix=prefix))
|
||||
|
||||
exprs = parse_schema(input_file)
|
||||
|
||||
@ -530,12 +481,4 @@ for expr in exprs:
|
||||
ret += generate_enum_declaration(expr['enum'], expr['data'])
|
||||
fdecl.write(ret)
|
||||
|
||||
fdecl.write('''
|
||||
#endif
|
||||
''')
|
||||
|
||||
fdecl.flush()
|
||||
fdecl.close()
|
||||
|
||||
fdef.flush()
|
||||
fdef.close()
|
||||
close_output(fdef, fdecl)
|
||||
|
244
scripts/qapi.py
244
scripts/qapi.py
@ -13,8 +13,11 @@
|
||||
|
||||
import re
|
||||
from ordereddict import OrderedDict
|
||||
import errno
|
||||
import getopt
|
||||
import os
|
||||
import sys
|
||||
import string
|
||||
|
||||
builtin_types = {
|
||||
'str': 'QTYPE_QSTRING',
|
||||
@ -537,7 +540,7 @@ def check_union(expr, expr_info):
|
||||
|
||||
# Otherwise, check for conflicts in the generated enum
|
||||
else:
|
||||
c_key = _generate_enum_string(key)
|
||||
c_key = camel_to_upper(key)
|
||||
if c_key in values:
|
||||
raise QAPIExprError(expr_info,
|
||||
"Union '%s' member '%s' clashes with '%s'"
|
||||
@ -555,7 +558,7 @@ def check_alternate(expr, expr_info):
|
||||
check_name(expr_info, "Member of alternate '%s'" % name, key)
|
||||
|
||||
# Check for conflicts in the generated enum
|
||||
c_key = _generate_enum_string(key)
|
||||
c_key = camel_to_upper(key)
|
||||
if c_key in values:
|
||||
raise QAPIExprError(expr_info,
|
||||
"Alternate '%s' member '%s' clashes with '%s'"
|
||||
@ -586,7 +589,7 @@ def check_enum(expr, expr_info):
|
||||
for member in members:
|
||||
check_name(expr_info, "Member of enum '%s'" %name, member,
|
||||
enum_member=True)
|
||||
key = _generate_enum_string(member)
|
||||
key = camel_to_upper(member)
|
||||
if key in values:
|
||||
raise QAPIExprError(expr_info,
|
||||
"Enum '%s' member '%s' clashes with '%s'"
|
||||
@ -728,17 +731,6 @@ def parse_args(typeinfo):
|
||||
# value of an optional argument.
|
||||
yield (argname, argentry, optional)
|
||||
|
||||
def de_camel_case(name):
|
||||
new_name = ''
|
||||
for ch in name:
|
||||
if ch.isupper() and new_name:
|
||||
new_name += '_'
|
||||
if ch == '-':
|
||||
new_name += '_'
|
||||
else:
|
||||
new_name += ch.lower()
|
||||
return new_name
|
||||
|
||||
def camel_case(name):
|
||||
new_name = ''
|
||||
first = True
|
||||
@ -752,7 +744,43 @@ def camel_case(name):
|
||||
new_name += ch.lower()
|
||||
return new_name
|
||||
|
||||
def c_var(name, protect=True):
|
||||
# ENUMName -> ENUM_NAME, EnumName1 -> ENUM_NAME1
|
||||
# ENUM_NAME -> ENUM_NAME, ENUM_NAME1 -> ENUM_NAME1, ENUM_Name2 -> ENUM_NAME2
|
||||
# ENUM24_Name -> ENUM24_NAME
|
||||
def camel_to_upper(value):
|
||||
c_fun_str = c_name(value, False)
|
||||
if value.isupper():
|
||||
return c_fun_str
|
||||
|
||||
new_name = ''
|
||||
l = len(c_fun_str)
|
||||
for i in range(l):
|
||||
c = c_fun_str[i]
|
||||
# When c is upper and no "_" appears before, do more checks
|
||||
if c.isupper() and (i > 0) and c_fun_str[i - 1] != "_":
|
||||
# Case 1: next string is lower
|
||||
# Case 2: previous string is digit
|
||||
if (i < (l - 1) and c_fun_str[i + 1].islower()) or \
|
||||
c_fun_str[i - 1].isdigit():
|
||||
new_name += '_'
|
||||
new_name += c
|
||||
return new_name.lstrip('_').upper()
|
||||
|
||||
def c_enum_const(type_name, const_name):
|
||||
return camel_to_upper(type_name + '_' + const_name)
|
||||
|
||||
c_name_trans = string.maketrans('.-', '__')
|
||||
|
||||
# Map @name to a valid C identifier.
|
||||
# If @protect, avoid returning certain ticklish identifiers (like
|
||||
# C keywords) by prepending "q_".
|
||||
#
|
||||
# Used for converting 'name' from a 'name':'type' qapi definition
|
||||
# into a generated struct member, as well as converting type names
|
||||
# into substrings of a generated C function name.
|
||||
# '__a.b_c' -> '__a_b_c', 'x-foo' -> 'x_foo'
|
||||
# protect=True: 'int' -> 'q_int'; protect=False: 'int' -> 'int'
|
||||
def c_name(name, protect=True):
|
||||
# ANSI X3J11/88-090, 3.1.1
|
||||
c89_words = set(['auto', 'break', 'case', 'char', 'const', 'continue',
|
||||
'default', 'do', 'double', 'else', 'enum', 'extern', 'float',
|
||||
@ -781,18 +809,27 @@ def c_var(name, protect=True):
|
||||
polluted_words = set(['unix', 'errno'])
|
||||
if protect and (name in c89_words | c99_words | c11_words | gcc_words | cpp_words | polluted_words):
|
||||
return "q_" + name
|
||||
return name.replace('-', '_').lstrip("*")
|
||||
|
||||
def c_fun(name, protect=True):
|
||||
return c_var(name, protect).replace('.', '_')
|
||||
return name.translate(c_name_trans)
|
||||
|
||||
# Map type @name to the C typedef name for the list form.
|
||||
#
|
||||
# ['Name'] -> 'NameList', ['x-Foo'] -> 'x_FooList', ['int'] -> 'intList'
|
||||
def c_list_type(name):
|
||||
return '%sList' % name
|
||||
return type_name(name) + 'List'
|
||||
|
||||
def type_name(name):
|
||||
if type(name) == list:
|
||||
return c_list_type(name[0])
|
||||
return name
|
||||
# Map type @value to the C typedef form.
|
||||
#
|
||||
# Used for converting 'type' from a 'member':'type' qapi definition
|
||||
# into the alphanumeric portion of the type for a generated C parameter,
|
||||
# as well as generated C function names. See c_type() for the rest of
|
||||
# the conversion such as adding '*' on pointer types.
|
||||
# 'int' -> 'int', '[x-Foo]' -> 'x_FooList', '__a.b_c' -> '__a_b_c'
|
||||
def type_name(value):
|
||||
if type(value) == list:
|
||||
return c_list_type(value[0])
|
||||
if value in builtin_types.keys():
|
||||
return value
|
||||
return c_name(value)
|
||||
|
||||
def add_name(name, info, meta, implicit = False):
|
||||
global all_names
|
||||
@ -849,42 +886,48 @@ def is_enum(name):
|
||||
return find_enum(name) != None
|
||||
|
||||
eatspace = '\033EATSPACE.'
|
||||
pointer_suffix = ' *' + eatspace
|
||||
|
||||
# Map type @name to its C type expression.
|
||||
# If @is_param, const-qualify the string type.
|
||||
#
|
||||
# This function is used for computing the full C type of 'member':'name'.
|
||||
# A special suffix is added in c_type() for pointer types, and it's
|
||||
# stripped in mcgen(). So please notice this when you check the return
|
||||
# value of c_type() outside mcgen().
|
||||
def c_type(name, is_param=False):
|
||||
if name == 'str':
|
||||
def c_type(value, is_param=False):
|
||||
if value == 'str':
|
||||
if is_param:
|
||||
return 'const char *' + eatspace
|
||||
return 'char *' + eatspace
|
||||
return 'const char' + pointer_suffix
|
||||
return 'char' + pointer_suffix
|
||||
|
||||
elif name == 'int':
|
||||
elif value == 'int':
|
||||
return 'int64_t'
|
||||
elif (name == 'int8' or name == 'int16' or name == 'int32' or
|
||||
name == 'int64' or name == 'uint8' or name == 'uint16' or
|
||||
name == 'uint32' or name == 'uint64'):
|
||||
return name + '_t'
|
||||
elif name == 'size':
|
||||
elif (value == 'int8' or value == 'int16' or value == 'int32' or
|
||||
value == 'int64' or value == 'uint8' or value == 'uint16' or
|
||||
value == 'uint32' or value == 'uint64'):
|
||||
return value + '_t'
|
||||
elif value == 'size':
|
||||
return 'uint64_t'
|
||||
elif name == 'bool':
|
||||
elif value == 'bool':
|
||||
return 'bool'
|
||||
elif name == 'number':
|
||||
elif value == 'number':
|
||||
return 'double'
|
||||
elif type(name) == list:
|
||||
return '%s *%s' % (c_list_type(name[0]), eatspace)
|
||||
elif is_enum(name):
|
||||
return name
|
||||
elif name == None or len(name) == 0:
|
||||
elif type(value) == list:
|
||||
return c_list_type(value[0]) + pointer_suffix
|
||||
elif is_enum(value):
|
||||
return c_name(value)
|
||||
elif value == None:
|
||||
return 'void'
|
||||
elif name in events:
|
||||
return '%sEvent *%s' % (camel_case(name), eatspace)
|
||||
elif value in events:
|
||||
return camel_case(value) + 'Event' + pointer_suffix
|
||||
else:
|
||||
return '%s *%s' % (name, eatspace)
|
||||
# complex type name
|
||||
assert isinstance(value, str) and value != ""
|
||||
return c_name(value) + pointer_suffix
|
||||
|
||||
def is_c_ptr(name):
|
||||
suffix = "*" + eatspace
|
||||
return c_type(name).endswith(suffix)
|
||||
def is_c_ptr(value):
|
||||
return c_type(value).endswith(pointer_suffix)
|
||||
|
||||
def genindent(count):
|
||||
ret = ""
|
||||
@ -938,29 +981,88 @@ def guardend(name):
|
||||
''',
|
||||
name=guardname(name))
|
||||
|
||||
# ENUMName -> ENUM_NAME, EnumName1 -> ENUM_NAME1
|
||||
# ENUM_NAME -> ENUM_NAME, ENUM_NAME1 -> ENUM_NAME1, ENUM_Name2 -> ENUM_NAME2
|
||||
# ENUM24_Name -> ENUM24_NAME
|
||||
def _generate_enum_string(value):
|
||||
c_fun_str = c_fun(value, False)
|
||||
if value.isupper():
|
||||
return c_fun_str
|
||||
def parse_command_line(extra_options = "", extra_long_options = []):
|
||||
|
||||
new_name = ''
|
||||
l = len(c_fun_str)
|
||||
for i in range(l):
|
||||
c = c_fun_str[i]
|
||||
# When c is upper and no "_" appears before, do more checks
|
||||
if c.isupper() and (i > 0) and c_fun_str[i - 1] != "_":
|
||||
# Case 1: next string is lower
|
||||
# Case 2: previous string is digit
|
||||
if (i < (l - 1) and c_fun_str[i + 1].islower()) or \
|
||||
c_fun_str[i - 1].isdigit():
|
||||
new_name += '_'
|
||||
new_name += c
|
||||
return new_name.lstrip('_').upper()
|
||||
try:
|
||||
opts, args = getopt.gnu_getopt(sys.argv[1:],
|
||||
"chp:o:" + extra_options,
|
||||
["source", "header", "prefix=",
|
||||
"output-dir="] + extra_long_options)
|
||||
except getopt.GetoptError, err:
|
||||
print >>sys.stderr, "%s: %s" % (sys.argv[0], str(err))
|
||||
sys.exit(1)
|
||||
|
||||
def generate_enum_full_value(enum_name, enum_value):
|
||||
abbrev_string = _generate_enum_string(enum_name)
|
||||
value_string = _generate_enum_string(enum_value)
|
||||
return "%s_%s" % (abbrev_string, value_string)
|
||||
output_dir = ""
|
||||
prefix = ""
|
||||
do_c = False
|
||||
do_h = False
|
||||
extra_opts = []
|
||||
|
||||
for oa in opts:
|
||||
o, a = oa
|
||||
if o in ("-p", "--prefix"):
|
||||
prefix = a
|
||||
elif o in ("-o", "--output-dir"):
|
||||
output_dir = a + "/"
|
||||
elif o in ("-c", "--source"):
|
||||
do_c = True
|
||||
elif o in ("-h", "--header"):
|
||||
do_h = True
|
||||
else:
|
||||
extra_opts.append(oa)
|
||||
|
||||
if not do_c and not do_h:
|
||||
do_c = True
|
||||
do_h = True
|
||||
|
||||
if len(args) != 1:
|
||||
print >>sys.stderr, "%s: need exactly one argument" % sys.argv[0]
|
||||
sys.exit(1)
|
||||
input_file = args[0]
|
||||
|
||||
return (input_file, output_dir, do_c, do_h, prefix, extra_opts)
|
||||
|
||||
def open_output(output_dir, do_c, do_h, prefix, c_file, h_file,
|
||||
c_comment, h_comment):
|
||||
c_file = output_dir + prefix + c_file
|
||||
h_file = output_dir + prefix + h_file
|
||||
|
||||
try:
|
||||
os.makedirs(output_dir)
|
||||
except os.error, e:
|
||||
if e.errno != errno.EEXIST:
|
||||
raise
|
||||
|
||||
def maybe_open(really, name, opt):
|
||||
if really:
|
||||
return open(name, opt)
|
||||
else:
|
||||
import StringIO
|
||||
return StringIO.StringIO()
|
||||
|
||||
fdef = maybe_open(do_c, c_file, 'w')
|
||||
fdecl = maybe_open(do_h, h_file, 'w')
|
||||
|
||||
fdef.write(mcgen('''
|
||||
/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
|
||||
%(comment)s
|
||||
''',
|
||||
comment = c_comment))
|
||||
|
||||
fdecl.write(mcgen('''
|
||||
/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
|
||||
%(comment)s
|
||||
#ifndef %(guard)s
|
||||
#define %(guard)s
|
||||
|
||||
''',
|
||||
comment = h_comment, guard = guardname(h_file)))
|
||||
|
||||
return (fdef, fdecl)
|
||||
|
||||
def close_output(fdef, fdecl):
|
||||
fdecl.write('''
|
||||
#endif
|
||||
''')
|
||||
fdecl.close()
|
||||
fdef.close()
|
||||
|
@ -301,24 +301,24 @@ tests/test-vmstate$(EXESUF): tests/test-vmstate.o \
|
||||
libqemuutil.a libqemustub.a
|
||||
|
||||
tests/test-qapi-types.c tests/test-qapi-types.h :\
|
||||
$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py
|
||||
$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
|
||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py \
|
||||
$(gen-out-type) -o tests -p "test-" -i $<, \
|
||||
$(gen-out-type) -o tests -p "test-" $<, \
|
||||
" GEN $@")
|
||||
tests/test-qapi-visit.c tests/test-qapi-visit.h :\
|
||||
$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-visit.py
|
||||
$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
|
||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py \
|
||||
$(gen-out-type) -o tests -p "test-" -i $<, \
|
||||
$(gen-out-type) -o tests -p "test-" $<, \
|
||||
" GEN $@")
|
||||
tests/test-qmp-commands.h tests/test-qmp-marshal.c :\
|
||||
$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-commands.py
|
||||
$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
|
||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \
|
||||
$(gen-out-type) -o tests -p "test-" -i $<, \
|
||||
$(gen-out-type) -o tests -p "test-" $<, \
|
||||
" GEN $@")
|
||||
tests/test-qapi-event.c tests/test-qapi-event.h :\
|
||||
$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-event.py
|
||||
$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-event.py $(qapi-py)
|
||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-event.py \
|
||||
$(gen-out-type) -o tests -p "test-" -i $<, \
|
||||
$(gen-out-type) -o tests -p "test-" $<, \
|
||||
" GEN $@")
|
||||
|
||||
tests/test-string-output-visitor$(EXESUF): tests/test-string-output-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a
|
||||
|
@ -107,3 +107,23 @@
|
||||
'data': { '*a': 'int', '*b': 'UserDefOne', 'c': 'str' } }
|
||||
{ 'event': 'EVENT_D',
|
||||
'data': { 'a' : 'EventStructOne', 'b' : 'str', '*c': 'str', '*enum3': 'EnumOne' } }
|
||||
|
||||
# test that we correctly compile downstream extensions
|
||||
{ 'enum': '__org.qemu_x-Enum', 'data': [ '__org.qemu_x-value' ] }
|
||||
{ 'struct': '__org.qemu_x-Base',
|
||||
'data': { '__org.qemu_x-member1': '__org.qemu_x-Enum' } }
|
||||
{ 'struct': '__org.qemu_x-Struct', 'base': '__org.qemu_x-Base',
|
||||
'data': { '__org.qemu_x-member2': 'str' } }
|
||||
{ 'union': '__org.qemu_x-Union1', 'data': { '__org.qemu_x-branch': 'str' } }
|
||||
{ 'struct': '__org.qemu_x-Struct2',
|
||||
'data': { 'array': ['__org.qemu_x-Union1'] } }
|
||||
{ 'union': '__org.qemu_x-Union2', 'base': '__org.qemu_x-Base',
|
||||
'discriminator': '__org.qemu_x-member1',
|
||||
'data': { '__org.qemu_x-value': '__org.qemu_x-Struct2' } }
|
||||
{ 'alternate': '__org.qemu_x-Alt',
|
||||
'data': { '__org.qemu_x-branch': 'str', 'b': '__org.qemu_x-Base' } }
|
||||
{ 'event': '__ORG.QEMU_X-EVENT', 'data': '__org.qemu_x-Struct' }
|
||||
{ 'command': '__org.qemu_x-command',
|
||||
'data': { 'a': ['__org.qemu_x-Enum'], 'b': ['__org.qemu_x-Struct'],
|
||||
'c': '__org.qemu_x-Union2', 'd': '__org.qemu_x-Alt' },
|
||||
'returns': '__org.qemu_x-Union1' }
|
||||
|
@ -22,10 +22,22 @@
|
||||
OrderedDict([('event', 'EVENT_A')]),
|
||||
OrderedDict([('event', 'EVENT_B'), ('data', OrderedDict())]),
|
||||
OrderedDict([('event', 'EVENT_C'), ('data', OrderedDict([('*a', 'int'), ('*b', 'UserDefOne'), ('c', 'str')]))]),
|
||||
OrderedDict([('event', 'EVENT_D'), ('data', OrderedDict([('a', 'EventStructOne'), ('b', 'str'), ('*c', 'str'), ('*enum3', 'EnumOne')]))])]
|
||||
OrderedDict([('event', 'EVENT_D'), ('data', OrderedDict([('a', 'EventStructOne'), ('b', 'str'), ('*c', 'str'), ('*enum3', 'EnumOne')]))]),
|
||||
OrderedDict([('enum', '__org.qemu_x-Enum'), ('data', ['__org.qemu_x-value'])]),
|
||||
OrderedDict([('struct', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member1', '__org.qemu_x-Enum')]))]),
|
||||
OrderedDict([('struct', '__org.qemu_x-Struct'), ('base', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member2', 'str')]))]),
|
||||
OrderedDict([('union', '__org.qemu_x-Union1'), ('data', OrderedDict([('__org.qemu_x-branch', 'str')]))]),
|
||||
OrderedDict([('struct', '__org.qemu_x-Struct2'), ('data', OrderedDict([('array', ['__org.qemu_x-Union1'])]))]),
|
||||
OrderedDict([('union', '__org.qemu_x-Union2'), ('base', '__org.qemu_x-Base'), ('discriminator', '__org.qemu_x-member1'), ('data', OrderedDict([('__org.qemu_x-value', '__org.qemu_x-Struct2')]))]),
|
||||
OrderedDict([('alternate', '__org.qemu_x-Alt'), ('data', OrderedDict([('__org.qemu_x-branch', 'str'), ('b', '__org.qemu_x-Base')]))]),
|
||||
OrderedDict([('event', '__ORG.QEMU_X-EVENT'), ('data', '__org.qemu_x-Struct')]),
|
||||
OrderedDict([('command', '__org.qemu_x-command'), ('data', OrderedDict([('a', ['__org.qemu_x-Enum']), ('b', ['__org.qemu_x-Struct']), ('c', '__org.qemu_x-Union2'), ('d', '__org.qemu_x-Alt')])), ('returns', '__org.qemu_x-Union1')])]
|
||||
[{'enum_name': 'EnumOne', 'enum_values': ['value1', 'value2', 'value3']},
|
||||
{'enum_name': '__org.qemu_x-Enum', 'enum_values': ['__org.qemu_x-value']},
|
||||
{'enum_name': 'UserDefAlternateKind', 'enum_values': None},
|
||||
{'enum_name': 'UserDefNativeListUnionKind', 'enum_values': None}]
|
||||
{'enum_name': 'UserDefNativeListUnionKind', 'enum_values': None},
|
||||
{'enum_name': '__org.qemu_x-Union1Kind', 'enum_values': None},
|
||||
{'enum_name': '__org.qemu_x-AltKind', 'enum_values': None}]
|
||||
[OrderedDict([('struct', 'NestedEnumsOne'), ('data', OrderedDict([('enum1', 'EnumOne'), ('*enum2', 'EnumOne'), ('enum3', 'EnumOne'), ('*enum4', 'EnumOne')]))]),
|
||||
OrderedDict([('struct', 'UserDefZero'), ('data', OrderedDict([('integer', 'int')]))]),
|
||||
OrderedDict([('struct', 'UserDefOne'), ('base', 'UserDefZero'), ('data', OrderedDict([('string', 'str'), ('*enum1', 'EnumOne')]))]),
|
||||
@ -37,4 +49,7 @@
|
||||
OrderedDict([('struct', 'UserDefC'), ('data', OrderedDict([('string1', 'str'), ('string2', 'str')]))]),
|
||||
OrderedDict([('struct', 'UserDefUnionBase'), ('data', OrderedDict([('string', 'str'), ('enum1', 'EnumOne')]))]),
|
||||
OrderedDict([('struct', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))]),
|
||||
OrderedDict([('struct', 'EventStructOne'), ('data', OrderedDict([('struct1', 'UserDefOne'), ('string', 'str'), ('*enum2', 'EnumOne')]))])]
|
||||
OrderedDict([('struct', 'EventStructOne'), ('data', OrderedDict([('struct1', 'UserDefOne'), ('string', 'str'), ('*enum2', 'EnumOne')]))]),
|
||||
OrderedDict([('struct', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member1', '__org.qemu_x-Enum')]))]),
|
||||
OrderedDict([('struct', '__org.qemu_x-Struct'), ('base', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member2', 'str')]))]),
|
||||
OrderedDict([('struct', '__org.qemu_x-Struct2'), ('data', OrderedDict([('array', ['__org.qemu_x-Union1'])]))])]
|
||||
|
@ -51,6 +51,21 @@ int64_t qmp_user_def_cmd3(int64_t a, bool has_b, int64_t b, Error **errp)
|
||||
return a + (has_b ? b : 0);
|
||||
}
|
||||
|
||||
__org_qemu_x_Union1 *qmp___org_qemu_x_command(__org_qemu_x_EnumList *a,
|
||||
__org_qemu_x_StructList *b,
|
||||
__org_qemu_x_Union2 *c,
|
||||
__org_qemu_x_Alt *d,
|
||||
Error **errp)
|
||||
{
|
||||
__org_qemu_x_Union1 *ret = g_new0(__org_qemu_x_Union1, 1);
|
||||
|
||||
ret->kind = ORG_QEMU_X_UNION1_KIND___ORG_QEMU_X_BRANCH;
|
||||
ret->__org_qemu_x_branch = strdup("blah1");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* test commands with no input and no return value */
|
||||
static void test_dispatch_cmd(void)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user