mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-24 01:25:40 +00:00
782a549898
Duplicated in commit 21cd70d. Yes, we can't import qapi-types, but that's no excuse. Move the helpers from qapi-types.py to qapi.py, and replace the duplicates in qapi-event.py. The generated event enumeration type's lookup table becomes const-correct (see commit 2e4450f), and uses explicit indexes instead of relying on order (see commit 912ae9c). Backports commit efd2eaa6c2992c214a13f102b6ddd4dca4697fb3 from qemu
238 lines
5.5 KiB
Python
238 lines
5.5 KiB
Python
#
|
|
# QAPI event generator
|
|
#
|
|
# Copyright (c) 2014 Wenchao Xia
|
|
#
|
|
# Authors:
|
|
# Wenchao Xia <wenchaoqemu@gmail.com>
|
|
#
|
|
# This work is licensed under the terms of the GNU GPL, version 2.
|
|
# See the COPYING file in the top-level directory.
|
|
|
|
from ordereddict import OrderedDict
|
|
from qapi import *
|
|
|
|
def _generate_event_api_name(event_name, params):
|
|
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_name(argname)
|
|
api_name += "".ljust(l)
|
|
|
|
api_name += "%s %s,\n" % (c_type(argentry, is_param=True),
|
|
c_name(argname))
|
|
api_name += "".ljust(l)
|
|
|
|
api_name += "Error **errp)"
|
|
return api_name;
|
|
|
|
|
|
# Following are the core functions that generate C APIs to emit event.
|
|
|
|
def generate_event_declaration(api_name):
|
|
return mcgen('''
|
|
|
|
%(api_name)s;
|
|
''',
|
|
api_name = api_name)
|
|
|
|
def generate_event_implement(api_name, event_name, params):
|
|
# step 1: declare any variables
|
|
ret = mcgen("""
|
|
|
|
%(api_name)s
|
|
{
|
|
QDict *qmp;
|
|
Error *local_err = NULL;
|
|
QMPEventFuncEmit emit;
|
|
""",
|
|
api_name = api_name)
|
|
|
|
if params:
|
|
ret += mcgen("""
|
|
QmpOutputVisitor *qov;
|
|
Visitor *v;
|
|
QObject *obj;
|
|
|
|
""")
|
|
|
|
# step 2: check emit function, create a dict
|
|
ret += mcgen("""
|
|
emit = qmp_event_get_func_emit();
|
|
if (!emit) {
|
|
return;
|
|
}
|
|
|
|
qmp = qmp_event_build_dict("%(event_name)s");
|
|
|
|
""",
|
|
event_name = event_name)
|
|
|
|
# step 3: visit the params if params != None
|
|
if params:
|
|
ret += mcgen("""
|
|
qov = qmp_output_visitor_new();
|
|
g_assert(qov);
|
|
|
|
v = qmp_output_get_visitor(qov);
|
|
g_assert(v);
|
|
|
|
/* Fake visit, as if all members are under a structure */
|
|
visit_start_struct(v, NULL, "", "%(event_name)s", 0, &local_err);
|
|
if (local_err) {
|
|
goto clean;
|
|
}
|
|
|
|
""",
|
|
event_name = event_name)
|
|
|
|
for argname, argentry, optional in parse_args(params):
|
|
if optional:
|
|
ret += mcgen("""
|
|
if (has_%(var)s) {
|
|
""",
|
|
var = c_name(argname))
|
|
push_indent()
|
|
|
|
if argentry == "str":
|
|
var_type = "(char **)"
|
|
else:
|
|
var_type = ""
|
|
|
|
ret += mcgen("""
|
|
visit_type_%(type)s(v, %(var_type)s&%(var)s, "%(name)s", &local_err);
|
|
if (local_err) {
|
|
goto clean;
|
|
}
|
|
""",
|
|
var_type = var_type,
|
|
var = c_name(argname),
|
|
type = type_name(argentry),
|
|
name = argname)
|
|
|
|
if optional:
|
|
pop_indent()
|
|
ret += mcgen("""
|
|
}
|
|
""")
|
|
|
|
ret += mcgen("""
|
|
|
|
visit_end_struct(v, &local_err);
|
|
if (local_err) {
|
|
goto clean;
|
|
}
|
|
|
|
obj = qmp_output_get_qobject(qov);
|
|
g_assert(obj != NULL);
|
|
|
|
qdict_put_obj(qmp, "data", obj);
|
|
""")
|
|
|
|
# step 4: call qmp event api
|
|
ret += mcgen("""
|
|
emit(%(event_enum_value)s, qmp, &local_err);
|
|
|
|
""",
|
|
event_enum_value = event_enum_value)
|
|
|
|
# step 5: clean up
|
|
if params:
|
|
ret += mcgen("""
|
|
clean:
|
|
qmp_output_visitor_cleanup(qov);
|
|
""")
|
|
ret += mcgen("""
|
|
error_propagate(errp, local_err);
|
|
QDECREF(qmp);
|
|
}
|
|
""")
|
|
|
|
return ret
|
|
|
|
(input_file, output_dir, do_c, do_h, prefix, dummy) = parse_command_line()
|
|
|
|
c_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.
|
|
*
|
|
*/
|
|
'''
|
|
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 "%(prefix)sqapi-event.h"
|
|
#include "%(prefix)sqapi-visit.h"
|
|
#include "qapi/qmp-output-visitor.h"
|
|
#include "qapi/qmp-event.h"
|
|
|
|
''',
|
|
prefix=prefix))
|
|
|
|
fdecl.write(mcgen('''
|
|
#include "qapi/error.h"
|
|
#include "qapi/qmp/qdict.h"
|
|
#include "%(prefix)sqapi-types.h"
|
|
|
|
''',
|
|
prefix=prefix))
|
|
|
|
exprs = QAPISchema(input_file).get_exprs()
|
|
|
|
event_enum_name = c_name(prefix + "QAPIEvent", protect=False)
|
|
event_names = []
|
|
|
|
for expr in exprs:
|
|
if expr.has_key('event'):
|
|
event_name = expr['event']
|
|
params = expr.get('data')
|
|
if params and len(params) == 0:
|
|
params = None
|
|
|
|
api_name = _generate_event_api_name(event_name, params)
|
|
ret = generate_event_declaration(api_name)
|
|
fdecl.write(ret)
|
|
|
|
# We need an enum value per event
|
|
event_enum_value = c_enum_const(event_enum_name, event_name)
|
|
ret = generate_event_implement(api_name, event_name, params)
|
|
fdef.write(ret)
|
|
|
|
# Record it, and generate enum later
|
|
event_names.append(event_name)
|
|
|
|
ret = generate_enum(event_enum_name, event_names)
|
|
fdecl.write(ret)
|
|
ret = generate_enum_lookup(event_enum_name, event_names)
|
|
fdef.write(ret)
|
|
|
|
close_output(fdef, fdecl)
|