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:
Peter Maydell 2015-05-15 17:51:20 +01:00
commit 385057cbec
15 changed files with 478 additions and 577 deletions

View File

@ -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 :\ 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) $(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.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 $@") " GEN $@")
qga/qapi-generated/qga-qapi-visit.c qga/qapi-generated/qga-qapi-visit.h :\ 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) $(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.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 $@") " GEN $@")
qga/qapi-generated/qga-qmp-commands.h qga/qapi-generated/qga-qmp-marshal.c :\ 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) $(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.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 $@") " GEN $@")
qapi-modules = $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi/common.json \ 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-types.c qapi-types.h :\
$(qapi-modules) $(SRC_PATH)/scripts/qapi-types.py $(qapi-py) $(qapi-modules) $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py \ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py \
$(gen-out-type) -o "." -b -i $<, \ $(gen-out-type) -o "." -b $<, \
" GEN $@") " GEN $@")
qapi-visit.c qapi-visit.h :\ qapi-visit.c qapi-visit.h :\
$(qapi-modules) $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py) $(qapi-modules) $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py \ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py \
$(gen-out-type) -o "." -b -i $<, \ $(gen-out-type) -o "." -b $<, \
" GEN $@") " GEN $@")
qapi-event.c qapi-event.h :\ qapi-event.c qapi-event.h :\
$(qapi-modules) $(SRC_PATH)/scripts/qapi-event.py $(qapi-py) $(qapi-modules) $(SRC_PATH)/scripts/qapi-event.py $(qapi-py)
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-event.py \ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-event.py \
$(gen-out-type) -o "." -b -i $<, \ $(gen-out-type) -o "." $<, \
" GEN $@") " GEN $@")
qmp-commands.h qmp-marshal.c :\ qmp-commands.h qmp-marshal.c :\
$(qapi-modules) $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py) $(qapi-modules) $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \
$(gen-out-type) -o "." -m -i $<, \ $(gen-out-type) -o "." -m $<, \
" GEN $@") " GEN $@")
QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qmp-commands.h) QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qmp-commands.h)

1
cpus.c
View File

@ -1435,6 +1435,7 @@ CpuInfoList *qmp_query_cpus(Error **errp)
info->value->CPU = cpu->cpu_index; info->value->CPU = cpu->cpu_index;
info->value->current = (cpu == first_cpu); info->value->current = (cpu == first_cpu);
info->value->halted = cpu->halted; info->value->halted = cpu->halted;
info->value->qom_path = object_get_canonical_path(OBJECT(cpu));
info->value->thread_id = cpu->thread_id; info->value->thread_id = cpu->thread_id;
#if defined(TARGET_I386) #if defined(TARGET_I386)
info->value->has_pc = true; info->value->has_pc = true;

View File

@ -536,7 +536,7 @@ created code.
Example: Example:
$ python scripts/qapi-types.py --output-dir="qapi-generated" \ $ 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 $ cat qapi-generated/example-qapi-types.c
[Uninteresting stuff omitted...] [Uninteresting stuff omitted...]
@ -623,7 +623,7 @@ $(prefix)qapi-visit.h: declarations for previously mentioned visitor
Example: Example:
$ python scripts/qapi-visit.py --output-dir="qapi-generated" $ 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 $ cat qapi-generated/example-qapi-visit.c
[Uninteresting stuff omitted...] [Uninteresting stuff omitted...]
@ -681,7 +681,7 @@ Example:
error_propagate(errp, err); error_propagate(errp, err);
} }
$ python scripts/qapi-commands.py --output-dir="qapi-generated" \ $ 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 $ cat qapi-generated/example-qapi-visit.h
[Uninteresting stuff omitted...] [Uninteresting stuff omitted...]
@ -715,7 +715,7 @@ $(prefix)qmp-commands.h: Function prototypes for the QMP commands
Example: Example:
$ python scripts/qapi-commands.py --output-dir="qapi-generated" $ 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 $ cat qapi-generated/example-qmp-marshal.c
[Uninteresting stuff omitted...] [Uninteresting stuff omitted...]
@ -806,7 +806,7 @@ $(prefix)qapi-event.c - Implementation of functions to send an event
Example: Example:
$ python scripts/qapi-event.py --output-dir="qapi-generated" $ 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 $ cat qapi-generated/example-qapi-event.c
[Uninteresting stuff omitted...] [Uninteresting stuff omitted...]

View File

@ -232,7 +232,7 @@ Example:
{ "event": "GUEST_PANICKED", { "event": "GUEST_PANICKED",
"data": { "action": "pause" } } "data": { "action": "pause" } }
MEM_HOT_UNPLUG_ERROR MEM_UNPLUG_ERROR
-------------------- --------------------
Emitted when memory hot unplug error occurs. Emitted when memory hot unplug error occurs.
@ -243,7 +243,7 @@ Data:
Example: Example:
{ "event": "MEM_HOT_UNPLUG_ERROR" { "event": "MEM_UNPLUG_ERROR"
"data": { "device": "dimm1", "data": { "device": "dimm1",
"msg": "acpi: device unplug for unsupported device" "msg": "acpi: device unplug for unsupported device"
}, },

View File

@ -679,6 +679,8 @@
# @halted: true if the virtual CPU is in the halt state. Halt usually refers # @halted: true if the virtual CPU is in the halt state. Halt usually refers
# to a processor specific low power mode. # 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 # @pc: #optional If the target is i386 or x86_64, this is the 64-bit instruction
# pointer. # pointer.
# If the target is Sparc, this is the PC component of the # 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. # data is sent to the client, the guest may no longer be halted.
## ##
{ 'struct': 'CpuInfo', { 'struct': 'CpuInfo',
'data': {'CPU': 'int', 'current': 'bool', 'halted': 'bool', '*pc': 'int', 'data': {'CPU': 'int', 'current': 'bool', 'halted': 'bool',
'*nip': 'int', '*npc': 'int', '*PC': 'int', 'thread_id': 'int'} } 'qom_path': 'str',
'*pc': 'int', '*nip': 'int', '*npc': 'int', '*PC': 'int',
'thread_id': 'int'} }
## ##
# @query-cpus: # @query-cpus:

View File

@ -2569,6 +2569,7 @@ Return a json-array. Each CPU is represented by a json-object, which contains:
- "CPU": CPU index (json-int) - "CPU": CPU index (json-int)
- "current": true if this is the current CPU, false otherwise (json-bool) - "current": true if this is the current CPU, false otherwise (json-bool)
- "halted": true if the cpu is halted, 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: - Current program counter. The key's name depends on the architecture:
"pc": i386/x86_64 (json-int) "pc": i386/x86_64 (json-int)
"nip": PPC (json-int) "nip": PPC (json-int)
@ -2585,14 +2586,16 @@ Example:
"CPU":0, "CPU":0,
"current":true, "current":true,
"halted":false, "halted":false,
"pc":3227107138 "qom_path":"/machine/unattached/device[0]",
"pc":3227107138,
"thread_id":3134 "thread_id":3134
}, },
{ {
"CPU":1, "CPU":1,
"current":false, "current":false,
"halted":true, "halted":true,
"pc":7108165 "qom_path":"/machine/unattached/device[2]",
"pc":7108165,
"thread_id":3135 "thread_id":3135
} }
] ]

View File

@ -15,28 +15,19 @@
from ordereddict import OrderedDict from ordereddict import OrderedDict
from qapi import * from qapi import *
import re 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): def generate_command_decl(name, args, ret_type):
arglist="" arglist=""
for argname, argtype, optional in parse_args(args): for argname, argtype, optional in parse_args(args):
argtype = c_type(argtype, is_param=True) argtype = c_type(argtype, is_param=True)
if optional: if optional:
arglist += "bool has_%s, " % c_var(argname) arglist += "bool has_%s, " % c_name(argname)
arglist += "%s %s, " % (argtype, c_var(argname)) arglist += "%s %s, " % (argtype, c_name(argname))
return mcgen(''' return mcgen('''
%(ret_type)s qmp_%(name)s(%(args)sError **errp); %(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): def gen_err_check(errvar):
if errvar: if errvar:
@ -55,14 +46,14 @@ def gen_sync_call(name, args, ret_type, indent=0):
retval = "retval = " retval = "retval = "
for argname, argtype, optional in parse_args(args): for argname, argtype, optional in parse_args(args):
if optional: if optional:
arglist += "has_%s, " % c_var(argname) arglist += "has_%s, " % c_name(argname)
arglist += "%s, " % (c_var(argname)) arglist += "%s, " % (c_name(argname))
push_indent(indent) push_indent(indent)
ret = mcgen(''' ret = mcgen('''
%(retval)sqmp_%(name)s(%(args)s&local_err); %(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: if ret_type:
ret += "\n" + gen_err_check('local_err') ret += "\n" + gen_err_check('local_err')
ret += "\n" + mcgen('''' 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): def gen_marshal_output_call(name, ret_type):
if not ret_type: if not ret_type:
return "" 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): def gen_visitor_input_containers_decl(args, obj):
ret = "" ret = ""
@ -101,17 +92,17 @@ def gen_visitor_input_vars_decl(args):
ret += mcgen(''' ret += mcgen('''
bool has_%(argname)s = false; bool has_%(argname)s = false;
''', ''',
argname=c_var(argname)) argname=c_name(argname))
if is_c_ptr(argtype): if is_c_ptr(argtype):
ret += mcgen(''' ret += mcgen('''
%(argtype)s %(argname)s = NULL; %(argtype)s %(argname)s = NULL;
''', ''',
argname=c_var(argname), argtype=c_type(argtype)) argname=c_name(argname), argtype=c_type(argtype))
else: else:
ret += mcgen(''' ret += mcgen('''
%(argtype)s %(argname)s = {0}; %(argtype)s %(argname)s = {0};
''', ''',
argname=c_var(argname), argtype=c_type(argtype)) argname=c_name(argname), argtype=c_type(argtype))
pop_indent() pop_indent()
return ret.rstrip() return ret.rstrip()
@ -144,18 +135,18 @@ v = qmp_input_get_visitor(mi);
ret += mcgen(''' ret += mcgen('''
visit_optional(v, &has_%(c_name)s, "%(name)s", %(errp)s); 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 += gen_err_check(errarg)
ret += mcgen(''' ret += mcgen('''
if (has_%(c_name)s) { if (has_%(c_name)s) {
''', ''',
c_name=c_var(argname)) c_name=c_name(argname))
push_indent() push_indent()
ret += mcgen(''' 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, c_name=c_name(argname), name=argname, argtype=argtype,
visitor=type_visitor(argtype), errp=errparg) visitor=type_name(argtype), errp=errparg)
ret += gen_err_check(errarg) ret += gen_err_check(errarg)
if optional: if optional:
pop_indent() 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; Visitor *v;
v = qmp_output_get_visitor(mo); 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) { if (local_err) {
goto out; goto out;
} }
@ -194,20 +185,20 @@ out:
qmp_output_visitor_cleanup(mo); qmp_output_visitor_cleanup(mo);
md = qapi_dealloc_visitor_new(); md = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(md); 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); qapi_dealloc_visitor_cleanup(md);
} }
''', ''',
c_ret_type=c_type(ret_type), c_name=c_fun(name), c_ret_type=c_type(ret_type), c_name=c_name(name),
visitor=type_visitor(ret_type)) visitor=type_name(ret_type))
return ret return ret
def gen_marshal_input_decl(name, args, ret_type, middle_mode): def gen_marshal_input_decl(name, args, ret_type, middle_mode):
if 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: 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(''' registry += mcgen('''
qmp_register_command("%(name)s", qmp_marshal_input_%(c_name)s, %(opts)s); 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) opts=options)
pop_indent() pop_indent()
ret = mcgen(''' ret = mcgen('''
@ -318,38 +309,20 @@ qapi_init(qmp_init_marshal);
registry=registry.rstrip()) registry=registry.rstrip())
return ret return ret
def gen_command_decl_prologue(header, guard, prefix=""): middle_mode = False
ret = mcgen('''
/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
/* (input_file, output_dir, do_c, do_h, prefix, opts) = \
* schema-defined QAPI function prototypes parse_command_line("m", ["middle"])
*
* 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 for o, a in opts:
#define %(guard)s if o in ("-m", "--middle"):
middle_mode = True
#include "%(prefix)sqapi-types.h" exprs = parse_schema(input_file)
#include "qapi/qmp/qdict.h" commands = filter(lambda expr: expr.has_key('command'), exprs)
#include "qapi/error.h" commands = filter(lambda expr: not expr.has_key('gen'), commands)
''',
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 */
c_comment = '''
/* /*
* schema-defined QMP->QAPI command dispatch * 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. * 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-common.h"
#include "qemu/module.h" #include "qemu/module.h"
#include "qapi/qmp/qerror.h" #include "qapi/qmp/qerror.h"
@ -374,82 +367,20 @@ def gen_command_def_prologue(prefix="", proxy=False):
#include "qapi/dealloc-visitor.h" #include "qapi/dealloc-visitor.h"
#include "%(prefix)sqapi-types.h" #include "%(prefix)sqapi-types.h"
#include "%(prefix)sqapi-visit.h" #include "%(prefix)sqapi-visit.h"
#include "%(prefix)sqmp-commands.h"
''', ''',
prefix=prefix) prefix=prefix))
if not proxy:
ret += '#include "%sqmp-commands.h"' % prefix
return ret + "\n\n"
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", prefix=prefix))
["source", "header", "prefix=",
"input-file=", "output-dir=",
"type=", "middle"])
except getopt.GetoptError, err:
print str(err)
sys.exit(1)
output_dir = "" for cmd in commands:
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:
arglist = [] arglist = []
ret_type = None ret_type = None
if cmd.has_key('data'): 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" ret = gen_marshal_input(cmd['command'], arglist, ret_type, middle_mode) + "\n"
fdef.write(ret) fdef.write(ret)
fdecl.write("\n#endif\n"); if not middle_mode:
if not middle_mode:
ret = gen_registry(commands) ret = gen_registry(commands)
fdef.write(ret) fdef.write(ret)
fdef.flush() close_output(fdef, fdecl)
fdef.close()
fdecl.flush()
fdecl.close()

View File

@ -11,23 +11,19 @@
from ordereddict import OrderedDict from ordereddict import OrderedDict
from qapi import * from qapi import *
import sys
import os
import getopt
import errno
def _generate_event_api_name(event_name, params): 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) l = len(api_name)
if params: if params:
for argname, argentry, optional in parse_args(params): for argname, argentry, optional in parse_args(params):
if optional: 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 += "".ljust(l)
api_name += "%s %s,\n" % (c_type(argentry, is_param=True), api_name += "%s %s,\n" % (c_type(argentry, is_param=True),
c_var(argname)) c_name(argname))
api_name += "".ljust(l) api_name += "".ljust(l)
api_name += "Error **errp)" api_name += "Error **errp)"
@ -98,7 +94,7 @@ def generate_event_implement(api_name, event_name, params):
ret += mcgen(""" ret += mcgen("""
if (has_%(var)s) { if (has_%(var)s) {
""", """,
var = c_var(argname)) var = c_name(argname))
push_indent() push_indent()
if argentry == "str": if argentry == "str":
@ -113,7 +109,7 @@ def generate_event_implement(api_name, event_name, params):
} }
""", """,
var_type = var_type, var_type = var_type,
var = c_var(argname), var = c_name(argname),
type = type_name(argentry), type = type_name(argentry),
name = argname) name = argname)
@ -177,7 +173,7 @@ typedef enum %(event_enum_name)s
event_enum_name = event_enum_name) event_enum_name = event_enum_name)
# append automatically generated _MAX value # 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 ] enum_values = event_enum_values + [ enum_max_value ]
i = 0 i = 0
@ -216,67 +212,9 @@ const char *%(event_enum_name)s_lookup[] = {
''') ''')
return ret return ret
(input_file, output_dir, do_c, do_h, prefix, dummy) = parse_command_line()
# Start the real job c_comment = '''
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 */
/* /*
* schema-defined QAPI event functions * schema-defined QAPI event functions
* *
@ -289,41 +227,43 @@ fdef.write(mcgen('''
* See the COPYING.LIB file in the top-level directory. * 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 "qemu-common.h"
#include "%(header)s" #include "%(prefix)sqapi-event.h"
#include "%(prefix)sqapi-visit.h" #include "%(prefix)sqapi-visit.h"
#include "qapi/qmp-output-visitor.h" #include "qapi/qmp-output-visitor.h"
#include "qapi/qmp-event.h" #include "qapi/qmp-event.h"
''', ''',
prefix=prefix, header=basename(h_file))) prefix=prefix))
fdecl.write(mcgen(''' 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/error.h"
#include "qapi/qmp/qdict.h" #include "qapi/qmp/qdict.h"
#include "%(prefix)sqapi-types.h" #include "%(prefix)sqapi-types.h"
''', ''',
prefix=prefix, guard=guardname(h_file))) prefix=prefix))
exprs = parse_schema(input_file) exprs = parse_schema(input_file)
@ -343,8 +283,7 @@ for expr in exprs:
fdecl.write(ret) fdecl.write(ret)
# We need an enum value per event # We need an enum value per event
event_enum_value = generate_enum_full_value(event_enum_name, event_enum_value = c_enum_const(event_enum_name, event_name)
event_name)
ret = generate_event_implement(api_name, event_name, params) ret = generate_event_implement(api_name, event_name, params)
fdef.write(ret) fdef.write(ret)
@ -357,12 +296,4 @@ fdecl.write(ret)
ret = generate_event_enum_lookup(event_enum_name, event_enum_strings) ret = generate_event_enum_lookup(event_enum_name, event_enum_strings)
fdef.write(ret) fdef.write(ret)
fdecl.write(''' close_output(fdef, fdecl)
#endif
''')
fdecl.flush()
fdecl.close()
fdef.flush()
fdef.close()

View File

@ -11,10 +11,6 @@
from ordereddict import OrderedDict from ordereddict import OrderedDict
from qapi import * from qapi import *
import sys
import os
import getopt
import errno
def generate_fwd_struct(name, members, builtin_type=False): def generate_fwd_struct(name, members, builtin_type=False):
if builtin_type: if builtin_type:
@ -45,7 +41,7 @@ typedef struct %(name)sList
struct %(name)sList *next; struct %(name)sList *next;
} %(name)sList; } %(name)sList;
''', ''',
name=name) name=c_name(name))
def generate_fwd_enum_struct(name, members): def generate_fwd_enum_struct(name, members):
return mcgen(''' return mcgen('''
@ -58,7 +54,7 @@ typedef struct %(name)sList
struct %(name)sList *next; struct %(name)sList *next;
} %(name)sList; } %(name)sList;
''', ''',
name=name) name=c_name(name))
def generate_struct_fields(members): def generate_struct_fields(members):
ret = '' ret = ''
@ -68,11 +64,11 @@ def generate_struct_fields(members):
ret += mcgen(''' ret += mcgen('''
bool has_%(c_name)s; bool has_%(c_name)s;
''', ''',
c_name=c_var(argname)) c_name=c_name(argname))
ret += mcgen(''' ret += mcgen('''
%(c_type)s %(c_name)s; %(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 return ret
@ -87,7 +83,7 @@ def generate_struct(expr):
struct %(name)s struct %(name)s
{ {
''', ''',
name=structname) name=c_name(structname))
if base: if base:
ret += generate_struct_fields({'base': base}) ret += generate_struct_fields({'base': base})
@ -115,16 +111,16 @@ def generate_enum_lookup(name, values):
ret = mcgen(''' ret = mcgen('''
const char *%(name)s_lookup[] = { const char *%(name)s_lookup[] = {
''', ''',
name=name) name=c_name(name))
i = 0 i = 0
for value in values: for value in values:
index = generate_enum_full_value(name, value) index = c_enum_const(name, value)
ret += mcgen(''' ret += mcgen('''
[%(index)s] = "%(value)s", [%(index)s] = "%(value)s",
''', ''',
index = index, value = value) index = index, value = value)
max_index = generate_enum_full_value(name, 'MAX') max_index = c_enum_const(name, 'MAX')
ret += mcgen(''' ret += mcgen('''
[%(max_index)s] = NULL, [%(max_index)s] = NULL,
}; };
@ -134,6 +130,7 @@ const char *%(name)s_lookup[] = {
return ret return ret
def generate_enum(name, values): def generate_enum(name, values):
name = c_name(name)
lookup_decl = mcgen(''' lookup_decl = mcgen('''
extern const char *%(name)s_lookup[]; extern const char *%(name)s_lookup[];
''', ''',
@ -150,7 +147,7 @@ typedef enum %(name)s
i = 0 i = 0
for value in enum_values: 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_decl += mcgen('''
%(enum_full_value)s = %(i)d, %(enum_full_value)s = %(i)d,
''', ''',
@ -173,18 +170,17 @@ def generate_alternate_qtypes(expr):
ret = mcgen(''' ret = mcgen('''
const int %(name)s_qtypes[QTYPE_MAX] = { const int %(name)s_qtypes[QTYPE_MAX] = {
''', ''',
name=name) name=c_name(name))
for key in members: for key in members:
qtype = find_alternate_member_qtype(members[key]) qtype = find_alternate_member_qtype(members[key])
assert qtype, "Invalid alternate member" assert qtype, "Invalid alternate member"
ret += mcgen(''' ret += mcgen('''
[ %(qtype)s ] = %(abbrev)s_KIND_%(enum)s, [%(qtype)s] = %(enum_const)s,
''', ''',
qtype = qtype, qtype = qtype,
abbrev = de_camel_case(name).upper(), enum_const = c_enum_const(name + 'Kind', key))
enum = c_fun(de_camel_case(key),False).upper())
ret += mcgen(''' ret += mcgen('''
}; };
@ -194,7 +190,7 @@ const int %(name)s_qtypes[QTYPE_MAX] = {
def generate_union(expr, meta): def generate_union(expr, meta):
name = expr[meta] name = c_name(expr[meta])
typeinfo = expr['data'] typeinfo = expr['data']
base = expr.get('base') base = expr.get('base')
@ -214,14 +210,14 @@ struct %(name)s
void *data; void *data;
''', ''',
name=name, name=name,
discriminator_type_name=discriminator_type_name) discriminator_type_name=c_name(discriminator_type_name))
for key in typeinfo: for key in typeinfo:
ret += mcgen(''' ret += mcgen('''
%(c_type)s %(c_name)s; %(c_type)s %(c_name)s;
''', ''',
c_type=c_type(typeinfo[key]), c_type=c_type(typeinfo[key]),
c_name=c_fun(key)) c_name=c_name(key))
ret += mcgen(''' ret += mcgen('''
}; };
@ -249,15 +245,15 @@ extern const int %(name)s_qtypes[];
def generate_type_cleanup_decl(name): def generate_type_cleanup_decl(name):
ret = mcgen(''' 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 return ret
def generate_type_cleanup(name): def generate_type_cleanup(name):
ret = mcgen(''' ret = mcgen('''
void qapi_free_%(type)s(%(c_type)s obj) void qapi_free_%(name)s(%(c_type)s obj)
{ {
QapiDeallocVisitor *md; QapiDeallocVisitor *md;
Visitor *v; Visitor *v;
@ -268,72 +264,23 @@ void qapi_free_%(type)s(%(c_type)s obj)
md = qapi_dealloc_visitor_new(); md = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(md); 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); qapi_dealloc_visitor_cleanup(md);
} }
''', ''',
c_type=c_type(name),type=name) c_type=c_type(name), name=c_name(name))
return ret 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 do_builtins = False
(input_file, output_dir, do_c, do_h, prefix, opts) = \
parse_command_line("b", ["builtins"])
for o, a in opts: for o, a in opts:
if o in ("-p", "--prefix"): if o in ("-b", "--builtins"):
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 do_builtins = True
if not do_c and not do_h: c_comment = '''
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 */
/* /*
* deallocation functions for schema-defined QAPI types * deallocation functions for schema-defined QAPI types
* *
@ -347,16 +294,8 @@ fdef.write(mcgen('''
* See the COPYING.LIB file in the top-level directory. * See the COPYING.LIB file in the top-level directory.
* *
*/ */
'''
#include "qapi/dealloc-visitor.h" h_comment = '''
#include "%(prefix)sqapi-types.h"
#include "%(prefix)sqapi-visit.h"
''', prefix=prefix))
fdecl.write(mcgen('''
/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
/* /*
* schema-defined QAPI types * schema-defined QAPI types
* *
@ -369,15 +308,25 @@ fdecl.write(mcgen('''
* See the COPYING.LIB file in the top-level directory. * See the COPYING.LIB file in the top-level directory.
* *
*/ */
'''
#ifndef %(guard)s (fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
#define %(guard)s '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 <stdbool.h>
#include <stdint.h> #include <stdint.h>
''', '''))
guard=guardname(h_file)))
exprs = parse_schema(input_file) exprs = parse_schema(input_file)
exprs = filter(lambda expr: not expr.has_key('gen'), exprs) exprs = filter(lambda expr: not expr.has_key('gen'), exprs)
@ -455,12 +404,4 @@ for expr in exprs:
continue continue
fdecl.write(ret) fdecl.write(ret)
fdecl.write(''' close_output(fdef, fdecl)
#endif
''')
fdecl.flush()
fdecl.close()
fdef.flush()
fdef.close()

View File

@ -15,10 +15,6 @@
from ordereddict import OrderedDict from ordereddict import OrderedDict
from qapi import * from qapi import *
import re import re
import sys
import os
import getopt
import errno
implicit_structs = [] implicit_structs = []
@ -56,7 +52,7 @@ static void visit_type_%(name)s_fields(Visitor *m, %(name)s **obj, Error **errp)
{ {
Error *err = NULL; Error *err = NULL;
''', ''',
name=name) name=c_name(name))
push_indent() push_indent()
if base: if base:
@ -66,7 +62,7 @@ if (err) {
goto out; 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): for argname, argentry, optional in parse_args(members):
if optional: if optional:
@ -74,13 +70,13 @@ if (err) {
visit_optional(m, &(*obj)->has_%(c_name)s, "%(name)s", &err); visit_optional(m, &(*obj)->has_%(c_name)s, "%(name)s", &err);
if (!err && (*obj)->has_%(c_name)s) { if (!err && (*obj)->has_%(c_name)s) {
''', ''',
c_name=c_var(argname), name=argname) c_name=c_name(argname), name=argname)
push_indent() push_indent()
ret += mcgen(''' ret += mcgen('''
visit_type_%(type)s(m, &(*obj)->%(c_name)s, "%(name)s", &err); 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) name=argname)
if optional: if optional:
@ -111,16 +107,16 @@ def generate_visit_struct_body(name, members):
ret = mcgen(''' ret = mcgen('''
Error *err = NULL; 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 (!err) {
if (*obj) { if (*obj) {
visit_type_%(name)s_fields(m, obj, errp); visit_type_%(c_name)s_fields(m, obj, errp);
} }
visit_end_struct(m, &err); visit_end_struct(m, &err);
} }
error_propagate(errp, err); error_propagate(errp, err);
''', ''',
name=name) name=name, c_name=c_name(name))
return ret 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) 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) ret += generate_visit_struct_body(name, members)
@ -173,7 +169,7 @@ out:
error_propagate(errp, err); error_propagate(errp, err);
} }
''', ''',
name=name) name=type_name(name))
def generate_visit_enum(name, members): def generate_visit_enum(name, members):
return mcgen(''' 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); 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): def generate_visit_alternate(name, members):
ret = mcgen(''' ret = mcgen('''
@ -202,11 +198,11 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **e
} }
switch ((*obj)->kind) { switch ((*obj)->kind) {
''', ''',
name=name) name=c_name(name))
# For alternate, always use the default enum type automatically generated # For alternate, always use the default enum type automatically generated
# as "'%sKind' % (name)" # as name + 'Kind'
disc_type = '%sKind' % (name) disc_type = c_name(name) + 'Kind'
for key in members: for key in members:
assert (members[key] in builtin_types.keys() 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_union(members[key])
or find_enum(members[key])), "Invalid alternate member" 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(''' ret += mcgen('''
case %(enum_full_value)s: case %(enum_full_value)s:
visit_type_%(c_type)s(m, &(*obj)->%(c_name)s, name, &err); 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, enum_full_value = enum_full_value,
c_type = type_name(members[key]), c_type = type_name(members[key]),
c_name = c_fun(key)) c_name = c_name(key))
ret += mcgen(''' ret += mcgen('''
default: default:
@ -252,12 +248,12 @@ def generate_visit_union(expr):
if enum_define: if enum_define:
# Use the enum type as discriminator # Use the enum type as discriminator
ret = "" ret = ""
disc_type = enum_define['enum_name'] disc_type = c_name(enum_define['enum_name'])
else: else:
# There will always be a discriminator in the C switch code, by default # There will always be a discriminator in the C switch code, by default
# it is an enum type generated silently as "'%sKind' % (name)" # it is an enum type generated silently
ret = generate_visit_enum('%sKind' % name, members.keys()) ret = generate_visit_enum(name + 'Kind', members.keys())
disc_type = '%sKind' % (name) disc_type = c_name(name) + 'Kind'
if base: if base:
assert discriminator assert discriminator
@ -281,7 +277,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **e
} }
if (*obj) { if (*obj) {
''', ''',
name=name) name=c_name(name))
if base: if base:
ret += mcgen(''' ret += mcgen('''
@ -290,7 +286,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **e
goto out_obj; goto out_obj;
} }
''', ''',
name=name) name=c_name(name))
if not discriminator: if not discriminator:
disc_key = "type" disc_key = "type"
@ -315,7 +311,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **e
else: else:
fmt = 'visit_type_implicit_%(c_type)s(m, &(*obj)->%(c_name)s, &err);' 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(''' ret += mcgen('''
case %(enum_full_value)s: case %(enum_full_value)s:
''' + fmt + ''' ''' + 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, enum_full_value = enum_full_value,
c_type=type_name(members[key]), c_type=type_name(members[key]),
c_name=c_fun(key)) c_name=c_name(key))
ret += mcgen(''' ret += mcgen('''
default: default:
@ -347,6 +343,7 @@ out:
def generate_declaration(name, members, builtin_type=False): def generate_declaration(name, members, builtin_type=False):
ret = "" ret = ""
if not builtin_type: if not builtin_type:
name = c_name(name)
ret += mcgen(''' ret += mcgen('''
void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **errp); 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(''' ret = mcgen('''
void visit_type_%(name)sList(Visitor *m, %(name)sList **obj, const char *name, Error **errp); void visit_type_%(name)sList(Visitor *m, %(name)sList **obj, const char *name, Error **errp);
''', ''',
name=name) name=c_name(name))
return ret 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); 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 do_builtins = False
(input_file, output_dir, do_c, do_h, prefix, opts) = \
parse_command_line("b", ["builtins"])
for o, a in opts: for o, a in opts:
if o in ("-p", "--prefix"): if o in ("-b", "--builtins"):
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 do_builtins = True
if not do_c and not do_h: c_comment = '''
do_c = True /*
do_h = True * 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 (fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
h_file = output_dir + prefix + h_file 'qapi-visit.c', 'qapi-visit.h',
c_comment, h_comment)
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(''' 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 "qemu-common.h"
#include "%(header)s" #include "%(prefix)sqapi-visit.h"
''', ''',
header=basename(h_file))) prefix = prefix))
fdecl.write(mcgen(''' 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 "qapi/visitor.h"
#include "%(prefix)sqapi-types.h" #include "%(prefix)sqapi-types.h"
''', ''',
prefix=prefix, guard=guardname(h_file))) prefix=prefix))
exprs = parse_schema(input_file) exprs = parse_schema(input_file)
@ -530,12 +481,4 @@ for expr in exprs:
ret += generate_enum_declaration(expr['enum'], expr['data']) ret += generate_enum_declaration(expr['enum'], expr['data'])
fdecl.write(ret) fdecl.write(ret)
fdecl.write(''' close_output(fdef, fdecl)
#endif
''')
fdecl.flush()
fdecl.close()
fdef.flush()
fdef.close()

View File

@ -13,8 +13,11 @@
import re import re
from ordereddict import OrderedDict from ordereddict import OrderedDict
import errno
import getopt
import os import os
import sys import sys
import string
builtin_types = { builtin_types = {
'str': 'QTYPE_QSTRING', 'str': 'QTYPE_QSTRING',
@ -537,7 +540,7 @@ def check_union(expr, expr_info):
# Otherwise, check for conflicts in the generated enum # Otherwise, check for conflicts in the generated enum
else: else:
c_key = _generate_enum_string(key) c_key = camel_to_upper(key)
if c_key in values: if c_key in values:
raise QAPIExprError(expr_info, raise QAPIExprError(expr_info,
"Union '%s' member '%s' clashes with '%s'" "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_name(expr_info, "Member of alternate '%s'" % name, key)
# Check for conflicts in the generated enum # Check for conflicts in the generated enum
c_key = _generate_enum_string(key) c_key = camel_to_upper(key)
if c_key in values: if c_key in values:
raise QAPIExprError(expr_info, raise QAPIExprError(expr_info,
"Alternate '%s' member '%s' clashes with '%s'" "Alternate '%s' member '%s' clashes with '%s'"
@ -586,7 +589,7 @@ def check_enum(expr, expr_info):
for member in members: for member in members:
check_name(expr_info, "Member of enum '%s'" %name, member, check_name(expr_info, "Member of enum '%s'" %name, member,
enum_member=True) enum_member=True)
key = _generate_enum_string(member) key = camel_to_upper(member)
if key in values: if key in values:
raise QAPIExprError(expr_info, raise QAPIExprError(expr_info,
"Enum '%s' member '%s' clashes with '%s'" "Enum '%s' member '%s' clashes with '%s'"
@ -728,17 +731,6 @@ def parse_args(typeinfo):
# value of an optional argument. # value of an optional argument.
yield (argname, argentry, optional) 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): def camel_case(name):
new_name = '' new_name = ''
first = True first = True
@ -752,7 +744,43 @@ def camel_case(name):
new_name += ch.lower() new_name += ch.lower()
return new_name 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 # ANSI X3J11/88-090, 3.1.1
c89_words = set(['auto', 'break', 'case', 'char', 'const', 'continue', c89_words = set(['auto', 'break', 'case', 'char', 'const', 'continue',
'default', 'do', 'double', 'else', 'enum', 'extern', 'float', 'default', 'do', 'double', 'else', 'enum', 'extern', 'float',
@ -781,18 +809,27 @@ def c_var(name, protect=True):
polluted_words = set(['unix', 'errno']) polluted_words = set(['unix', 'errno'])
if protect and (name in c89_words | c99_words | c11_words | gcc_words | cpp_words | polluted_words): if protect and (name in c89_words | c99_words | c11_words | gcc_words | cpp_words | polluted_words):
return "q_" + name return "q_" + name
return name.replace('-', '_').lstrip("*") return name.translate(c_name_trans)
def c_fun(name, protect=True):
return c_var(name, protect).replace('.', '_')
# 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): def c_list_type(name):
return '%sList' % name return type_name(name) + 'List'
def type_name(name): # Map type @value to the C typedef form.
if type(name) == list: #
return c_list_type(name[0]) # Used for converting 'type' from a 'member':'type' qapi definition
return name # 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): def add_name(name, info, meta, implicit = False):
global all_names global all_names
@ -849,42 +886,48 @@ def is_enum(name):
return find_enum(name) != None return find_enum(name) != None
eatspace = '\033EATSPACE.' 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 # 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 # stripped in mcgen(). So please notice this when you check the return
# value of c_type() outside mcgen(). # value of c_type() outside mcgen().
def c_type(name, is_param=False): def c_type(value, is_param=False):
if name == 'str': if value == 'str':
if is_param: if is_param:
return 'const char *' + eatspace return 'const char' + pointer_suffix
return 'char *' + eatspace return 'char' + pointer_suffix
elif name == 'int': elif value == 'int':
return 'int64_t' return 'int64_t'
elif (name == 'int8' or name == 'int16' or name == 'int32' or elif (value == 'int8' or value == 'int16' or value == 'int32' or
name == 'int64' or name == 'uint8' or name == 'uint16' or value == 'int64' or value == 'uint8' or value == 'uint16' or
name == 'uint32' or name == 'uint64'): value == 'uint32' or value == 'uint64'):
return name + '_t' return value + '_t'
elif name == 'size': elif value == 'size':
return 'uint64_t' return 'uint64_t'
elif name == 'bool': elif value == 'bool':
return 'bool' return 'bool'
elif name == 'number': elif value == 'number':
return 'double' return 'double'
elif type(name) == list: elif type(value) == list:
return '%s *%s' % (c_list_type(name[0]), eatspace) return c_list_type(value[0]) + pointer_suffix
elif is_enum(name): elif is_enum(value):
return name return c_name(value)
elif name == None or len(name) == 0: elif value == None:
return 'void' return 'void'
elif name in events: elif value in events:
return '%sEvent *%s' % (camel_case(name), eatspace) return camel_case(value) + 'Event' + pointer_suffix
else: 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): def is_c_ptr(value):
suffix = "*" + eatspace return c_type(value).endswith(pointer_suffix)
return c_type(name).endswith(suffix)
def genindent(count): def genindent(count):
ret = "" ret = ""
@ -938,29 +981,88 @@ def guardend(name):
''', ''',
name=guardname(name)) name=guardname(name))
# ENUMName -> ENUM_NAME, EnumName1 -> ENUM_NAME1 def parse_command_line(extra_options = "", extra_long_options = []):
# 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
new_name = '' try:
l = len(c_fun_str) opts, args = getopt.gnu_getopt(sys.argv[1:],
for i in range(l): "chp:o:" + extra_options,
c = c_fun_str[i] ["source", "header", "prefix=",
# When c is upper and no "_" appears before, do more checks "output-dir="] + extra_long_options)
if c.isupper() and (i > 0) and c_fun_str[i - 1] != "_": except getopt.GetoptError, err:
# Case 1: next string is lower print >>sys.stderr, "%s: %s" % (sys.argv[0], str(err))
# Case 2: previous string is digit sys.exit(1)
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 generate_enum_full_value(enum_name, enum_value): output_dir = ""
abbrev_string = _generate_enum_string(enum_name) prefix = ""
value_string = _generate_enum_string(enum_value) do_c = False
return "%s_%s" % (abbrev_string, value_string) 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()

View File

@ -301,24 +301,24 @@ tests/test-vmstate$(EXESUF): tests/test-vmstate.o \
libqemuutil.a libqemustub.a libqemuutil.a libqemustub.a
tests/test-qapi-types.c tests/test-qapi-types.h :\ 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 \ $(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 $@") " GEN $@")
tests/test-qapi-visit.c tests/test-qapi-visit.h :\ 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 \ $(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 $@") " GEN $@")
tests/test-qmp-commands.h tests/test-qmp-marshal.c :\ 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 \ $(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 $@") " GEN $@")
tests/test-qapi-event.c tests/test-qapi-event.h :\ 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 \ $(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 $@") " GEN $@")
tests/test-string-output-visitor$(EXESUF): tests/test-string-output-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a tests/test-string-output-visitor$(EXESUF): tests/test-string-output-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a

View File

@ -107,3 +107,23 @@
'data': { '*a': 'int', '*b': 'UserDefOne', 'c': 'str' } } 'data': { '*a': 'int', '*b': 'UserDefOne', 'c': 'str' } }
{ 'event': 'EVENT_D', { 'event': 'EVENT_D',
'data': { 'a' : 'EventStructOne', 'b' : 'str', '*c': 'str', '*enum3': 'EnumOne' } } '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' }

View File

@ -22,10 +22,22 @@
OrderedDict([('event', 'EVENT_A')]), OrderedDict([('event', 'EVENT_A')]),
OrderedDict([('event', 'EVENT_B'), ('data', OrderedDict())]), OrderedDict([('event', 'EVENT_B'), ('data', OrderedDict())]),
OrderedDict([('event', 'EVENT_C'), ('data', OrderedDict([('*a', 'int'), ('*b', 'UserDefOne'), ('c', 'str')]))]), 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': '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': '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', 'NestedEnumsOne'), ('data', OrderedDict([('enum1', 'EnumOne'), ('*enum2', 'EnumOne'), ('enum3', 'EnumOne'), ('*enum4', 'EnumOne')]))]),
OrderedDict([('struct', 'UserDefZero'), ('data', OrderedDict([('integer', 'int')]))]), OrderedDict([('struct', 'UserDefZero'), ('data', OrderedDict([('integer', 'int')]))]),
OrderedDict([('struct', 'UserDefOne'), ('base', 'UserDefZero'), ('data', OrderedDict([('string', 'str'), ('*enum1', 'EnumOne')]))]), 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', 'UserDefC'), ('data', OrderedDict([('string1', 'str'), ('string2', 'str')]))]),
OrderedDict([('struct', 'UserDefUnionBase'), ('data', OrderedDict([('string', 'str'), ('enum1', 'EnumOne')]))]), 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', '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'])]))])]

View File

@ -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); 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 */ /* test commands with no input and no return value */
static void test_dispatch_cmd(void) static void test_dispatch_cmd(void)
{ {